繁体   English   中英

如何在 Django Rest Framework 中为用户登录创建 Json Web 令牌?

[英]How to create Json Web Token to User login in Django Rest Framework?

我想将 JWT 集成到我的用户登录 API 以进行身份​​验证。 我如何将它与我在下面添加的现有代码集成。 在代码中,我添加了一个需要相应更改的虚拟令牌。 谢谢。

从我的 django 项目中添加一些相关的代码部分以供参考:

序列化器

class UserLoginSerializer(ModelSerializer):
token = CharField(allow_blank=True, read_only=True)

class Meta:
    model = User
    fields = [
        'username',
        'password',
        'token',
    ]
    extra_kwargs = {"password":
                        {"write_only": True}
                    }

def validate(self, data):
    user_obj = None
    username = data.get("username", None)
    password = data["password"]
    if not username:
        raise ValidationError("Kullanıcı adı gerekli.")

    user = User.objects.filter(
        Q(username=username)
        ).distinct()
    user = user.exclude(email__isnull=True).exclude(email__iexact='')
    if user.exists() and user.count() == 1:
        user = user.first()
    else:
        raise ValidationError("Böyle bir Kullanıcı Adı yoktur.")

    if user_obj:
        if not user_obj.check_password(password):
            raise ValidationError("Tekrar deneyiniz.")
    data["token"] = "asdasdasdasd"
    return data

观看次数

class UserLoginAPIView(APIView):
permission_classes = [AllowAny]
serializer_class = UserLoginSerializer

def post(self, request, *args, **kwargs):
    data = request.data
    serializer = UserLoginSerializer(data=data)
    if serializer.is_valid(raise_exception=True):
        new_data = serializer.data
        return Response(new_data, status=HTTP_200_OK)
    return Response(serializer.errors, status=HTTP_400_BAD_REQUEST)

设置

REST_FRAMEWORK = {
'DEFAULT_PERMISSION_CLASSES': (
    'rest_framework.permissions.IsAuthenticated',
    ),
'DEFAULT_AUTHENTICATION_CLASSES': (
    'rest_framework.authentication.SessionAuthentication',
    'rest_framework.authentication.BasicAuthentication',
    'rest_framework_jwt.authentication.JSONWebTokenAuthentication',
    ),
}

网址

urlpatterns = [
    url(r'^login/$', UserLoginAPIView.as_view(), name='login'),
    url(r'^api-token-auth/', obtain_jwt_token),
    url(r'^api-token-refresh/', refresh_jwt_token),
    url(r'^api-token-verify/', verify_jwt_token),
    url(r'^register/$', UserCreateAPIView.as_view(), name='register'),
]

您可以使用其内置视图rest_framework_jwt.views.obtain_jwt_token进行用户登录。

它创建一个令牌。

然后您需要转到RestrictedView并使用令牌进行身份验证。 仅此而已。

使用名为PyJWT的库在 Python 中使用 JWT 的更简单方法

步骤:

  1. 安装 jwt 的 pip 包( $ pip install PyJWT
  2. 在views.py:

     import jwt
  3. 然后转到要生成令牌的地方,然后按如下方式使用它:

     encoded = jwt.encode({'email': uemail, 'phone':phone}, 'MySecretKey', algorithm='HS256')
  4. 在响应中打印或添加编码变量,将给出响应。

你可以尝试做这样的事情:

首先,安装pip install djangorestframework-jwt

设置.py:

REST_FRAMEWORK = {
    'DEFAULT_PERMISSION_CLASSES': (
        'rest_framework.permissions.IsAuthenticated',
    ),
    'DEFAULT_AUTHENTICATION_CLASSES': (
        'rest_framework.authentication.SessionAuthentication',
        'rest_framework.authentication.BasicAuthentication',
        'rest_framework_jwt.authentication.JSONWebTokenAuthentication',
    ),
}

def jwt_response_payload_handler(token, user, request, *args, **kwargs):
    data = {
        "token": token,
        "user": "{}".format(user.id),
        "userid": user.id,
        "active": user.is_active
    }
    return data

JWT_AUTH = {
    'JWT_RESPONSE_PAYLOAD_HANDLER': 'jwt_response_payload_handler',
    'JWT_EXPIRATION_DELTA': datetime.timedelta(days=180),
    'JWT_ALLOW_REFRESH': False,
    'JWT_REFRESH_EXPIRATION_DELTA': datetime.timedelta(days=30),
    'JWT_SECRET_KEY': 'generate_a_secret_key',
}

序列化程序.py:

from rest_framework import serializers
from rest_framework.authtoken.models import Token

class TokenSerializer(serializers.ModelSerializer):
    class Meta:
        model = Token
        fields = ('key',)

任何地方authenication_classes适用于您的视图,您都需要添加:

from rest_framework_jwt.authentication import JSONWebTokenAuthentication

我希望对你有帮助!

我实现了一个使用 JWT 登录的方法,它的作用是:

  1. 获取随请求发送的电子邮件和密码并将其转换为字符串变量
  2. 我检查电子邮件是否已存在于我制作的自定义用户模型中。
  3. 如果用户已经存在,我将对象模型转换为字典,以便我可以获得其特定的密码。
  4. 我匹配与用户模型对应的密码和随 post 请求发送的密码。
  5. 如果电子邮件存在于用户模型中,并且与该用户模型对应的密码与随发布请求一起发送的密码匹配,我将使用 pyJWT 使用我的自定义数据制作 JWT 并返回响应。
  6. 在所有其他情况下,电子邮件和密码不匹配,我返回“不匹配”

假设请求是 {"email":"xyz@gmail.com", "password":"12345" }

    @api_view(['POST'])
    def signin(request):

    email = list(request.data.values())[0] #gets email value from post request {"email":"xyz@gmail.com", "password":"123"} -> this xyz@gmail.com
    password = list(request.data.values())[1] #gets password value from post request {"email":"xyz@gmail.com", "password":"123"} -> this 123

    usr = User.objects.filter(email=email).exists() #checks if email exists
    if usr:
      dictionary = User.objects.filter(email=email).values()[0] #converts object to dictionary for accessing data like dictionary["password"] dictionary["first_name"] etc
      if usr and dictionary["password"] == password: #check if email and its corresponing password stored matches the password that is sent
        branch = dictionary["branch"]
        id = dictionary["id"]
        encoded_jwt = jwt.encode({'email': email,}, 'secret', algorithm='HS256')
        return Response({'token':encoded_jwt,'email':email,'branch':branch,'id':id})
      else: 
        return Response({'No Match'})
    return Response({'No Match'})

我实现了一个使用 JWT 登录的方法,它的作用是:

  1. 获取随请求发送的电子邮件和密码并将其转换为字符串变量
  2. 我检查电子邮件是否已存在于我制作的自定义用户模型中。
  3. 如果用户已经存在,我将对象模型转换为字典,以便我可以获得其特定的密码。
  4. 我匹配与用户模型对应的密码和随 post 请求发送的密码。
  5. 如果电子邮件存在于用户模型中,并且与该用户模型对应的密码与随发布请求一起发送的密码匹配,我将使用 pyJWT 使用我的自定义数据制作 JWT 并返回响应。
  6. 在所有其他情况下,电子邮件和密码不匹配,我返回“不匹配”

假设请求是 {"email":"xyz@gmail.com", "password":"12345" }

视图.py

    @api_view(['POST'])
    def signin(request):

    email = list(request.data.values())[0] #gets email value from post request {"email":"xyz@gmail.com", "password":"123"} -> this xyz@gmail.com
    password = list(request.data.values())[1] #gets password value from post request {"email":"xyz@gmail.com", "password":"123"} -> this 123

    usr = User.objects.filter(email=email).exists() #checks if email exists
    if usr:
      dictionary = User.objects.filter(email=email).values()[0] #converts object to dictionary for accessing data like dictionary["password"] dictionary["first_name"] etc
      if usr and dictionary["password"] == password: #check if email and its corresponing password stored matches the password that is sent
        branch = dictionary["branch"]
        id = dictionary["id"]
        encoded_jwt = jwt.encode({'email': email,}, 'secret', algorithm='HS256')
        return Response({'token':encoded_jwt,'email':email,'branch':branch,'id':id})
      else: 
        return Response({'No Match'})
    return Response({'No Match'})

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM