JWT安裝配置

瑤瑤y發表於2020-10-05

1.登入介面 
2.重新整理介面 
3.自定義返回格式

1.1安裝JWT

pip install djangorestframework-jwt==1.11.0

1.2syl/settings.py 配置jwt載荷中的有效期設定

# jwt載荷中的有效期設定 
JWT_AUTH = {    
	# 1.token字首:headers中 Authorization 值的字首    
	'JWT_AUTH_HEADER_PREFIX': 'JWT',    
	# 2.token有效期:一天有效    	
	'JWT_EXPIRATION_DELTA': datetime.timedelta(days=1),    
	# 3.重新整理token:允許使用舊的token換新token    
	'JWT_ALLOW_REFRESH': True,    
	# 4.token有效期:token在24小時內過期, 可續期token    
	'JWT_REFRESH_EXPIRATION_DELTA': datetime.timedelta(hours=24),    
	# 5.自定義JWT載荷資訊:自定義返回格式,需要手工建立    
	'JWT_RESPONSE_PAYLOAD_HANDLER': 'user.utils.jwt_response_payload_handler', 
}

1.3 syl/settings.py JWT結合DRF進行認證許可權配置

# 在DRF配置檔案中開啟認證和許可權 REST_FRAMEWORK = {    
	...    
	# 使用者登陸認證方式    
	'DEFAULT_AUTHENTICATION_CLASSES': [        		
		'rest_framework_jwt.authentication.JSONWebTokenAuthentication',    # 在 DRF中配置JWT認證        
		# 'rest_framework.authentication.SessionAuthentication',  # 使用session時 的認證器        
		# 'rest_framework.authentication.BasicAuthentication'     # 提交表單時的認 證器    ],    
		# 許可權配置, 順序靠上的嚴格    
		'DEFAULT_PERMISSION_CLASSES': [        
			#'rest_framework.permissions.IsAdminUser',                # 管理員可以訪問        
			'rest_framework.permissions.IsAuthenticated',              # 全域性配置只有認 證使用者可以訪問介面        
			# 'rest_framework.permissions.IsAuthenticatedOrReadOnly',  # 認證使用者可以訪 問, 否則只能讀取        
			# 'rest_framework.permissions.AllowAny',                   # 所有使用者都可以 訪問    
	],    
	... 
}

1.5 在user/utils.py中從寫jwt_response_payload_handler

def jwt_response_payload_handler(token, user=None, request=None, role=None):    
	"""
    自定義jwt認證成功返回資料    
    :token  返回的jwt    
    :user   當前登入的使用者資訊[物件]    
    :request 當前本次客戶端提交過來的資料    
    :role 角色    
    """    
    if user.first_name:        
    	name = user.first_name    
    else:        
    	name = user.username    
    return {        
    	'authenticated': 'true',        
    	'id': user.id,        
    	"role": role,        
    	'name': name,        
    	'username': user.username,        
    	'email': user.email,        
    	'token': token,    
}

2. postman測試介面

2.1 測試登入介面,獲取token

http://192.168.56.100:8888/user/login/

在這裡插入圖片描述

'''自定義認證和許可權優先順序更高,可以覆蓋settings.py中的 ''' 
# 自定義許可權類 permission_classes = (MyPermission,) 
# 自定義認證類, 自定義會覆蓋全域性配置 
authentication_classes = (JSONWebTokenAuthentication,)

2.2 使用獲得的token獲取所有使用者資訊

http://192.168.56.100:8888/user/user/

在這裡插入圖片描述
在這裡插入圖片描述

3.原始碼分析

class JSONWebTokenAPIView(APIView):    
	"""    
	Base API View that various JWT interactions inherit from.    
	"""    
	permission_classes = ()    
	authentication_classes = ()
	
    def get_serializer_context(self):        
    	"""        
    	Extra context provided to the serializer class.        
    	"""        
    	return {
 			'request': self.request,            
 			'view': self,        
 		}
    def get_serializer_class(self):        
    	"""        
    	Return the class to use for the serializer.        Defaults to using `self.serializer_class`.        You may want to override this if you need to provide different        serializations depending on the incoming request.        (Eg. admins get full serialization, others get basic serialization)        
    	"""        
    	assert self.serializer_class is not None, (            
    		"'%s' should either include a `serializer_class` attribute, "            
    		"or override the `get_serializer_class()` method."            
    		% self.__class__.__name__)        
    	return self.serializer_class
    def get_serializer(self, *args, **kwargs):        
    	"""        
    	Return the serializer instance that should be used for validating and        
    	deserializing input, and for serializing output.        
    	"""        
    	serializer_class = self.get_serializer_class()        
    	kwargs['context'] = self.get_serializer_context()        
    	return serializer_class(*args, **kwargs)
    	
    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   # User表物件            
        	token = serializer.object.get('token')                 # 獲取到生成的 token            
        	response_data = jwt_response_payload_handler(token, user, request)            
        	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)

相關文章