如何在Django中使用令牌返回用户ID?

时间:2017-06-09 03:36:29

标签: python django python-2.7 authorization token

我使用Django中的默认视图生成标记:

margin: 0 auto;
background-image: url(../IMG/contactpage1[2742].jpg);
background-position: center center;
background-size: cover;
height: 350px;
width: 370px;

我遇到问题,因为我的前端不知道当前登录的用户ID是什么。

我应该使用令牌返回它还是创建另一个请求?

我知道有很多不同的方法,但我想选择最佳解决方案。

4 个答案:

答案 0 :(得分:11)

您可以覆盖rest_framework.authtoken.views.ObtainAuthToken.post以获得所需的结果。

<强>的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()),
]

示例结果

$ 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"
}

这里的想法是覆盖ObtainAuthToken视图类的post方法。这里我所做的就是调用父类获取令牌,然后查找该令牌以查找关联的用户ID。

希望有所帮助。

答案 1 :(得分:1)

如果您需要在网页上获取用户信息,则需要在Login API或其他API的响应中传递用户信息。

在使用基于令牌的身份验证时,在登录后,会生成访问令牌和刷新令牌,这些令牌应在登录API响应中提供给客户端。此访问令牌应在标题中传递:

Authorization : Bearer <insert token here>

你需要放authentication_classes = [OAuth2Authentication] 在你看来。

这将验证用户是否已登录,您还可以user=request.user访问登录用户的信息。

答案 2 :(得分:0)

我认为好的做法是在login api的响应中返回用户详细信息。

如果您的built_in视图没有返回用户详细信息,则可以覆盖obtain_auth_token的post方法。我曾经为djangorestframework-jwt获取令牌方法

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)

默认情况下response_data dict只有token个详细信息,我添加了用户对象以实现您的目标。

答案 3 :(得分:0)

我不仅需要带有令牌的用户ID,所以我做了代码以返回整个用户对象:

*我使用的是自定义用户,因此,如果您使用的是django默认用户,请将型号和序列化程序更改为默认用户。

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})

通过此线程,操作起来很简单!希望我的回答也能节省别人的时间。 :)