简体   繁体   English

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

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

I want to integrate JWT to my User login API for Authentication.我想将 JWT 集成到我的用户登录 API 以进行身份​​验证。 How can I integrate it with my existing code that I have added below.我如何将它与我在下面添加的现有代码集成。 In the code I have added a dummy token that needs to be changed accordingly.在代码中,我添加了一个需要相应更改的虚拟令牌。 Thank you.谢谢。

Adding some relevant parts of code from my django project for reference:从我的 django 项目中添加一些相关的代码部分以供参考:

Serializers序列化器

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

Views观看次数

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)

Settings设置

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

urls网址

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'),
]

You can use its in-built view rest_framework_jwt.views.obtain_jwt_token for User Login.您可以使用其内置视图rest_framework_jwt.views.obtain_jwt_token进行用户登录。

It creates a token.它创建一个令牌。

And then you need to go to RestrictedView and use the token for authentication.然后您需要转到RestrictedView并使用令牌进行身份验证。 That's all.仅此而已。

More easiest way to use JWT in Python using the library called PyJWT使用名为PyJWT的库在 Python 中使用 JWT 的更简单方法

Steps:步骤:

  1. Install pip package of jwt ( $ pip install PyJWT )安装 jwt 的 pip 包( $ pip install PyJWT
  2. At the views.py:在views.py:

     import jwt
  3. Then goto the place, where you wanted to generate a token, then use it as follows:然后转到要生成令牌的地方,然后按如下方式使用它:

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

You can try doing something like this:你可以尝试做这样的事情:

First, install pip install djangorestframework-jwt .首先,安装pip install djangorestframework-jwt

settings.py:设置.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',
}

serializers.py:序列化程序.py:

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

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

Anywhere authenication_classes apply in your views , you'll want to add:任何地方authenication_classes适用于您的视图,您都需要添加:

from rest_framework_jwt.authentication import JSONWebTokenAuthentication

I hope that helps you!我希望对你有帮助!

I implemented a method for Sign In with JWT and what it does is:我实现了一个使用 JWT 登录的方法,它的作用是:

  1. Fetches the email and password that is send with the request and converts it into a string variable获取随请求发送的电子邮件和密码并将其转换为字符串变量
  2. I check if the email already exists in the custom user model i made.我检查电子邮件是否已存在于我制作的自定义用户模型中。
  3. If the user already exists, i convert the object model to dictionary so that i can get its particular password.如果用户已经存在,我将对象模型转换为字典,以便我可以获得其特定的密码。
  4. In that i match the password corresponding to user model and the password that is send with the post request.我匹配与用户模型对应的密码和随 post 请求发送的密码。
  5. if the email exists in the user model and the password corresponding to that user model matches the password that is sent with the post request i use the pyJWT to make the JWT with my custom data and return the response.如果电子邮件存在于用户模型中,并且与该用户模型对应的密码与随发布请求一起发送的密码匹配,我将使用 pyJWT 使用我的自定义数据制作 JWT 并返回响应。
  6. In all other cases the email and password don't match and i return "No Match"在所有其他情况下,电子邮件和密码不匹配,我返回“不匹配”

Suppose the request is {"email":"xyz@gmail.com", "password":"12345" }假设请求是 {"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'})

I implemented a method for Sign In with JWT and what it does is:我实现了一个使用 JWT 登录的方法,它的作用是:

  1. Fetches the email and password that is send with the request and converts it into a string variable获取随请求发送的电子邮件和密码并将其转换为字符串变量
  2. I check if the email already exists in the custom user model i made.我检查电子邮件是否已存在于我制作的自定义用户模型中。
  3. If the user already exists, i convert the object model to dictionary so that i can get its particular password.如果用户已经存在,我将对象模型转换为字典,以便我可以获得其特定的密码。
  4. In that i match the password corresponding to user model and the password that is send with the post request.我匹配与用户模型对应的密码和随 post 请求发送的密码。
  5. if the email exists in the user model and the password corresponding to that user model matches the password that is sent with the post request i use the pyJWT to make the JWT with my custom data and return the response.如果电子邮件存在于用户模型中,并且与该用户模型对应的密码与随发布请求一起发送的密码匹配,我将使用 pyJWT 使用我的自定义数据制作 JWT 并返回响应。
  6. In all other cases the email and password don't match and i return "No Match"在所有其他情况下,电子邮件和密码不匹配,我返回“不匹配”

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

views.py视图.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