How can I return user ID with token in Django?

后端 未结 4 906
广开言路
广开言路 2020-12-21 00:34

I generate tokens using default view in Django:

url(r\'^login/\', rest_auth_views.obtain_auth_token),

I have a problem because my front-end

相关标签:
4条回答
  • 2020-12-21 01:15

    if you need to get user information on a webpage, you need to pass user information in a response of Login API or other API.

    While using Token based authentication, after login, access token and refresh token are generated which are shall be given to client in login API response. This access token shall be passed in header as:

    Authorization : Bearer <insert token here>
    

    You need to put authentication_classes = [OAuth2Authentication] in your view.

    This will validate the if user is logged in also you will get to access logged in user's information by user=request.user.

    0 讨论(0)
  • 2020-12-21 01:19

    I think the good practice will be to return user details in the response of login api.

    If your built_in view doesn't return user details you can may be override the post method of obtain_auth_token. I once did this for djangorestframework-jwt obtain token method

    def post(self, request, *args, **kwargs):
        serializer = self.get_serializer(data=request.data)
    
        if serializer.is_valid():
            user = serializer.object.get('user') or request.user
            token = serializer.object.get('token')
            response_data = {
                'token': token,
                'user': UserSerializer(user).data
            }
            response = Response(response_data, status=status.HTTP_200_OK)
            if api_settings.JWT_AUTH_COOKIE:
                expiration = (datetime.utcnow() +
                              api_settings.JWT_EXPIRATION_DELTA)
                response.set_cookie(api_settings.JWT_AUTH_COOKIE,
                                    response.data['token'],
                                    expires=expiration,
                                    httponly=True)
            return response
    
        return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)
    

    by default response_data dict only had token details i added user object as well to achieve what you are trying to do.

    0 讨论(0)
  • 2020-12-21 01:27

    You could override rest_framework.authtoken.views.ObtainAuthToken.post in order to get the result you want.

    myapp/views.py

    from rest_framework.authtoken.views import ObtainAuthToken
    from rest_framework.authtoken.models import Token
    from rest_framework.response import Response
    
    
    class CustomObtainAuthToken(ObtainAuthToken):
        def post(self, request, *args, **kwargs):
            response = super(CustomObtainAuthToken, self).post(request, *args, **kwargs)
            token = Token.objects.get(key=response.data['token'])
            return Response({'token': token.key, 'id': token.user_id})
    

    myapp/urls.py

    from django.conf.urls import url
    
    from .views import CustomObtainAuthToken
    
    urlpatterns = [
        url(r'^authenticate/', CustomObtainAuthToken.as_view()),
    ]
    

    Sample results

    $ http :8000/authenticate/ username=someuser password=secretpassword
    HTTP/1.0 200 OK
    Allow: POST, OPTIONS
    Content-Language: en
    Content-Type: application/json
    Date: Tue, 22 Mar 2017 18:30:10 GMT
    Server: WSGIServer/0.2 CPython/3.5.1
    Vary: Accept-Language, Cookie
    X-Frame-Options: SAMEORIGIN
    
    {
        "id": 16, 
        "token": "82e0bc9980a6b2c9a70969b0f8dc974418dda399"
    }
    

    The idea here is to override the post method of the ObtainAuthToken view class. Here all I have done is call the parent class to get the token, then look up that token to find the associated user id.

    Hope that helps.

    0 讨论(0)
  • 2020-12-21 01:37

    I needed more than just user id with the token, so I did code to return the whole user object:

    *I use custom user, so if you are using django default user, change model and serializer to default.

    from users.serializers import CustomUserSerializer
    from users.models import CustomUser
    
    
    class CustomObtainAuthToken(ObtainAuthToken):
        def post(self, request, *args, **kwargs):
            response = super(CustomObtainAuthToken, self).post(request, *args, **kwargs)
            token = Token.objects.get(key=response.data['token'])
            user = CustomUser.objects.get(id=token.user_id)
            return Response({'token': token.key, 'user': CustomUserSerializer(user).data})
    

    Thanks to this thread it was easy! Hope my answer will save someones time too. :)

    0 讨论(0)
提交回复
热议问题