django如何生成唯一的用户令牌

django如何生成唯一的用户令牌,django,Django,我对令牌身份验证有点困惑。经过几次提问和尝试后,我已经成功地为我的用户创建了自动登录的url网关,但我只能通过使用user\u id并将其发送到url中,例如http://example.com/auth/login/?user_id=12但我更愿意使用?令牌= 我正在使用一个示例,说明如何生成自定义身份验证令牌,并使用该令牌返回有关我的用户的更多数据,以便在我卷曲到url之后返回 {“令牌”:“D5D86E55FD5DDD4829B2AC72C3ED96B7E30DD86”,“用户id”:52

我对令牌身份验证有点困惑。经过几次提问和尝试后,我已经成功地为我的用户创建了自动登录的
url
网关,但我只能通过使用
user\u id
并将其发送到
url
中,例如
http://example.com/auth/login/?user_id=12
但我更愿意使用
?令牌=

我正在使用一个示例,说明如何生成自定义身份验证令牌,并使用该令牌返回有关我的用户的更多数据,以便在我卷曲到
url之后返回

{“令牌”:“D5D86E55FD5DDD4829B2AC72C3ED96B7E30DD86”,“用户id”:52}

现在我面临的问题是这很正常,我的模型中没有令牌,所以我创建了一个

token=models.CharField(最大长度=125,null=True,blank=True)

所以我可以克服DoesNotExist的错误,但是错误仍然存在

我用这个黑客来登录网关

from django.contrib.auth import authenticate, login
from django.core.urlresolvers import reverse
from django.views.generic import View
from django.http import HttpResponseRedirect

from business_accounts.models.my_user import MyUser


class UrlGatewayLogin(View):

    def get(self, request, **kwargs):
        page_group = kwargs.get('page_group')
        token = request.GET.get('token')
        user = MyUser.objects.get(token=token)
        user.backend = 'django.contrib.auth.backends.ModelBackend'
        login(request, user)

        return HttpResponseRedirect(reverse('dashboard', args=(page_group, )))

DRF令牌是否每个用户都是唯一的,如何在django中生成令牌并将其用于网关?

您需要安装django Rest Framework并在设置中启用令牌身份验证

首先,您必须为您的用户模型编写一个序列化程序,然后为令牌身份验证创建一个带有序列化数据的api视图

例如(您也可以使用用户名而不是电子邮件): 在users/api/serializers.py文件中:

from django.utils.translation import ugettext_lazy as _

from rest_framework import serializers
from rest_framework.compat import authenticate

from ..models import User


class AuthTokenSerializer(serializers.Serializer):
    email = serializers.EmailField(label=_("Email Address"))
    password = serializers.CharField(
        label=_("Password"),
        style={'input_type': 'password'},
        trim_whitespace=False
    )

    def validate(self, data):
        email = data.get('email')
        password = data.get('password')

        if email and password:
            user = authenticate(email=email, password=password)

            if user:
                if not user.is_active:
                    msg = _('User account is deactivated.')
                    raise serializers.ValidationError(msg)
            else:
                msg = _('Unable to log in with provided credentials.')
                raise serializers.ValidationError(msg)
        else:
            msg = _('Must include "email" and "password".')
            raise serializers.ValidationError(msg)

        data['user'] = user
        return data
from rest_framework.response import Response

from .serializers import AuthTokenSerializer
from ..models import User


class ObtainAuthToken(APIView):
    throttle_classes = ()
    permission_classes = ()
    parser_classes = (parsers.FormParser, parsers.MultiPartParser, parsers.JSONParser,)
    renderer_classes = (renderers.JSONRenderer,)
    serializer_class = AuthTokenSerializer

    def post(self, request, *args, **kwargs):
        serializer = self.serializer_class(data=request.data,
                                           context={'request': request})
        serializer.is_valid(raise_exception=True)
        user = serializer.validated_data['user']
        token, created = Token.objects.get_or_create(user=user)
        return Response({'token': token.key, 'username':user.username})
然后在users/api/views.py文件中:

from django.utils.translation import ugettext_lazy as _

from rest_framework import serializers
from rest_framework.compat import authenticate

from ..models import User


class AuthTokenSerializer(serializers.Serializer):
    email = serializers.EmailField(label=_("Email Address"))
    password = serializers.CharField(
        label=_("Password"),
        style={'input_type': 'password'},
        trim_whitespace=False
    )

    def validate(self, data):
        email = data.get('email')
        password = data.get('password')

        if email and password:
            user = authenticate(email=email, password=password)

            if user:
                if not user.is_active:
                    msg = _('User account is deactivated.')
                    raise serializers.ValidationError(msg)
            else:
                msg = _('Unable to log in with provided credentials.')
                raise serializers.ValidationError(msg)
        else:
            msg = _('Must include "email" and "password".')
            raise serializers.ValidationError(msg)

        data['user'] = user
        return data
from rest_framework.response import Response

from .serializers import AuthTokenSerializer
from ..models import User


class ObtainAuthToken(APIView):
    throttle_classes = ()
    permission_classes = ()
    parser_classes = (parsers.FormParser, parsers.MultiPartParser, parsers.JSONParser,)
    renderer_classes = (renderers.JSONRenderer,)
    serializer_class = AuthTokenSerializer

    def post(self, request, *args, **kwargs):
        serializer = self.serializer_class(data=request.data,
                                           context={'request': request})
        serializer.is_valid(raise_exception=True)
        user = serializer.validated_data['user']
        token, created = Token.objects.get_or_create(user=user)
        return Response({'token': token.key, 'username':user.username})
然后在“设置”中,确保已启用令牌身份验证:

REST_FRAMEWORK = {
    'DEFAULT_RENDERER_CLASSES': (
        'rest_framework.renderers.JSONRenderer',
    ),
    'DEFAULT_AUTHENTICATION_CLASSES': (
        'rest_framework.authentication.TokenAuthentication',
    ),
    'DEFAULT_PERMISSION_CLASSES': (
        'rest_framework.permissions.IsAuthenticated',
    )
}
为了使用该令牌返回有关用户的数据,您需要在用户模型上编写另一个序列化程序,包括要返回的字段,例如:

class UserDetailSerializer(serializers.ModelSerializer):
    class Meta:
        model = User
        fields = [
            'username', 'email', 'hobbies', 'language',
            'gender', 'birthday'
        ]
并编写另一个api视图,例如:

class UserDetailAPIView(RetrieveAPIView):
    permission_classes = [IsAuthenticated]
    serializer_class = UserDetailSerializer

    def get_object(self):
        obj = get_object_or_404(User, username=self.request.user.username)
        return obj

关键是为您的模型编写序列化程序,以便数据可以在Internet上传输。

看看这个JWT,这很好,但我已经尝试过了,我已经对JWT进行了设置,问题是它的重点是API,我正在尝试为标准Django构建它。一切都准备好了,系统无法识别该令牌对该用户是唯一的。@PetarP令牌类似于密码。它不必是独一无二的。您可以将令牌与用户名或电子邮件一起使用。