首页 > 编程语言 > rest_framework_jwt源码分析

rest_framework_jwt源码分析

时间:2023-02-09 19:56:59浏览次数:46  
标签:username settings api self jwt framework 源码 user payload

rest_framework_jwt源码分析之序列化类

序列化类
class JSONWebTokenSerializer(Serializer):
    def __init__(self, *args, **kwargs):
  		# 这里是给序列化类的对象,添加两个字段,self.username_field字段其实就是我们在auth表中的字段
      # password就是一个只写用来反序列化的字段
        super(JSONWebTokenSerializer, self).__init__(*args, **kwargs)

        self.fields[self.username_field] = serializers.CharField()
        self.fields['password'] = PasswordField(write_only=True)

    @property  # 这个方法就是用来取模型AbstractUser模型表中的字段,默认是username
    			# 如果报错的话,还是使用username这个字段
    def username_field(self):
        return get_username_field()
	
    # 这是一个全局钩子,校验前端传来的用户信息
    def validate(self, attrs):
        # self就是序列化类的对象,attrs就是前端传来的登录信息
        credentials = {
         # 定义一个字典,一个是username:前端传来的用户名,password:前端传来的password
            self.username_field: attrs.get(self.username_field),
            'password': attrs.get('password')
        }
		# credentials.values()一次性获取字典所有的值,如果都为True
        # 这里用了方法all就是所有结果都为True,才为True
        if all(credentials.values()):
            # 如果用户名和密码有值,那么用authenticate方法,打散
	# 这里回顾django的auth的authenticate方法,给他用户名和密码会返回一个用户对象
            user = authenticate(**credentials)
		# 如果这个用户对象有值
            if user:
          # 这么这句话不知道是判断什么的,user是auth表的对象,如果是AbstractUser表模型的方法,默认就是True,所以不会走这里
                if not user.is_active:
                    msg = _('User account is disabled.')
                    raise serializers.ValidationError(msg)
			# 这句话执行的是默认配置方法里面的jwt_payload_handler(user)将user传入
                payload = jwt_payload_handler(user)
    # 这里的payload其实是payload = {
    #    'user_id': user.pk,
     #    'username': username,
     #   'exp': datetime.utcnow() + api_settings.JWT_EXPIRATION_DELTA,
     #   还有一个用户名的字段
    }
                return {
                    # 这里的方法应该就是获取token,这里的token就是加密以后的
                    'token': jwt_encode_handler(payload),
                 # user就是当前的用户对象
                    'user': user
                }
            else:
                msg = _('Unable to log in with provided credentials.')
                raise serializers.ValidationError(msg)
        else:
            msg = _('Must include "{username_field}" and "password".')
            msg = msg.format(username_field=self.username_field)
            raise serializers.ValidationError(msg)
 

def jwt_payload_handler(user):
    # 第一句表示获取表里面的username字段
    username_field = get_username_field()
    # 第二个表示从user里面拿到用户名
    username = get_username(user)
# 定义一个payload字典,里面放user的id,用户名,以及当前utc时间和过期时间
    payload = {
        'user_id': user.pk,
        'username': username,
        'exp': datetime.utcnow() + api_settings.JWT_EXPIRATION_DELTA
    }
    if hasattr(user, 'email'):
        payload['email'] = user.email
    if isinstance(user.pk, uuid.UUID):
        payload['user_id'] = str(user.pk)

    payload[username_field] = username

# 这里又调用了一个配置的方法,其实这几个值默认都是None,是给荷载里面添加一些东西
    if api_settings.JWT_ALLOW_REFRESH:
        payload['orig_iat'] = timegm(
            datetime.utcnow().utctimetuple()
        )

    if api_settings.JWT_AUDIENCE is not None:
        payload['aud'] = api_settings.JWT_AUDIENCE

    if api_settings.JWT_ISSUER is not None:
        payload['iss'] = api_settings.JWT_ISSUER
# 最后将payload返回
    return payload



# 对荷载进行加密
def jwt_encode_handler(payload):
    # 这里是拿到秘钥
    key = api_settings.JWT_PRIVATE_KEY or jwt_get_secret_key(payload)
    # 这一步就是将加密的返回出去
    return jwt.encode(
        # 荷载的内容
        payload,
        # 秘钥
        key,
        # 加密模式'HS256'
        api_settings.JWT_ALGORITHM
    ).decode('utf-8')

rest_framework_jwt源码分析之视图类

继承的APIView应该是一个post请求
from rest_framework.views import APIView
from rest_framework import status
from rest_framework.response import Response
from datetime import datetime

from .settings import api_settings
from .serializers import (
    JSONWebTokenSerializer, RefreshJSONWebTokenSerializer,
    VerifyJSONWebTokenSerializer
)
从导模块看他具体使用了什么序列化类

class JSONWebTokenAPIView(APIView):
		# 这里很多代码都删了,看不懂
    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 = jwt_response_payload_handler(token, user, request)
            # 生成一个Response对象,然后最后将这个对象返回出去
            response = Response(response_data)
            if api_settings.JWT_AUTH_COOKIE:
                expiration = (datetime.utcnow() +
                              api_settings.JWT_EXPIRATION_DELTA)
                response.set_cookie(api_settings.JWT_AUTH_COOKIE,
                                    token,
                                    expires=expiration,
                                    httponly=True)
            return response

        return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)

标签:username,settings,api,self,jwt,framework,源码,user,payload
From: https://www.cnblogs.com/zhanghong1229/p/17106828.html

相关文章