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的自定义方法 }