Django REST Framework JWT提供了一個視圖。在我們登錄的時候,會校驗用戶名、密碼是否正確。如果信息無誤,可以返回一個JWT token。就可以簡單地實現了記錄用戶登錄狀態。
用法:
只需要在路由配置一下即可:
from rest_framework_jwt.views import obtain_jwt_token urlpatterns=[ ... url(r'login$',obtain_jwt_token) ]
這樣就可以實現登錄之后,返回JWT token了。
至於obtain_jwt_token是怎么實現校驗和返回JWT token的功能的呢?
可以看一下源碼,我簡單看了下,原理大體如下:
1 # 真正起作用的是ObtainJSONWebToken視圖 2 obtain_jwt_token = ObtainJSONWebToken.as_view() 3 4 5 # (點進ObtainJSONWebToken) 6 # ObtainJSONWebToken是一個DRF子類視圖 7 class ObtainJSONWebToken(JSONWebTokenAPIView): 8 # JSONWebTokenSerializer先通過django的設置文件獲取到用戶的模型類,然后獲取到模型類的用戶名字段。然后自己建立一個序列化器,包括用戶名、密碼字段。 9 serializer_class = JSONWebTokenSerializer 10 11 12 # (點進JSONWebTokenAPIView) 13 class JSONWebTokenAPIView(APIView): 14 def post(self, request, *args, **kwargs): 15 # 取得自己建立的序列化器 16 serializer = self.get_serializer(data=request.data) 17 # 校驗成功后的操作 18 if serializer.is_valid(): 19 user = serializer.object.get('user') or request.user 20 token = serializer.object.get('token') 21 # response_data就是返回的數據。 22 response_data = jwt_response_payload_handler(token, user, request) 23 response = Response(response_data) 24 ... 25 ... 26 return response 27 28 return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST) 29 30 31 # (搜索jwt_response_payload_handler) 32 # 可以看到jwt_response_payload_handler返回一個字典,包含着JWT token 33 def jwt_response_payload_handler(token, user=None, request=None): 34 """ 35 Returns the response data for both the login and refresh views. 36 Override to return a custom response such as including the 37 serialized representation of the User. 38 39 Example: 40 41 def jwt_response_payload_handler(token, user=None, request=None): 42 return { 43 'token': token, 44 'user': UserSerializer(user, context={'request': request}).data 45 } 46 47 """ 48 return { 49 'token': token 50 }
這就是實現登錄后自動返回token的原理。
-
需求&解決
現在有一個需求,登錄成功后,不僅僅返回JWT token,還要返回username和user_id。應該怎么修改呢?
如果認真看上面的源碼,其實已經知道怎么解決了。
就是重寫33行的jwt_response_payload_handler函數。
def jwt_response_payload_handler(token,user=None,request=None): return { "token":token, "id":user.id, "username":user.username }
因為重寫了方法,要應用我們自定義的方法,需要在django上進行設置。
JWT_AUTH = { ... 'JWT_RESPONSE_PAYLOAD_HANDLER': 'user.utils.jwt_response_payload_handler', # 應用登錄返回token的自定義方法 }