1.JWT安装配置
1.1安装JWT
pip install djangorestframework
-jwt
==1.11.0
1.2syl/settings.py配置jwt载荷中的有效期设置
JWT_AUTH
= {
'JWT_AUTH_HEADER_PREFIX': 'JWT',
'JWT_EXPIRATION_DELTA': datetime
.timedelta
(days
=1),
'JWT_ALLOW_REFRESH': True,
'JWT_REFRESH_EXPIRATION_DELTA': datetime
.timedelta
(hours
=24),
'JWT_RESPONSE_PAYLOAD_HANDLER': 'user.utils.jwt_response_payload_handler',
}
1.3syl/settings.pyJWT结合DRF进行认证权限配置
1.4user/urls.py增加获取token接口和刷新token接口
from django
.urls
import include
, path
from rest_framework
.authtoken
.views
import obtain_auth_token
from user
import views
from rest_framework
.routers
import SimpleRouter
, DefaultRouter
from rest_framework_jwt
.views
import obtain_jwt_token
, refresh_jwt_token
router
= DefaultRouter
()
router
.register
(r
'user', views
.UserViewSet
)
urlpatterns
= [
path
('index/', views
.index
),
path
('login/', obtain_jwt_token
),
path
('refresh/', refresh_jwt_token
),
path
('api-auth/', include
('rest_framework.urls',
namespace
='rest_framework')),
]
urlpatterns
+= router
.urls
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
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
)