Django 实现JWT登录认证
依赖:
Django版本:2.2.5
djangorestframework:3.12.1
djangorestframework-jwt:1.11.0
废话不说直接上代码:
主urls.py文件(ratelimt用于登录频繁限制)
-
from django.contrib import admin
-
from django.urls import path,include,re_path
-
from rest_framework_jwt.views import obtain_jwt_token
-
from ratelimit.decorators import ratelimit
-
-
-
urlpatterns = [
-
# jwt的认证接口
-
re_path('api/(?P<version>[v1|v2] )/login/$', ratelimit(key='ip', method='POST', rate='1/6s',block=True)(obtain_jwt_token)),
-
]
settings配置:
-
-
JWT_AUTH = {
-
'JWT_EXPIRATION_DELTA': datetime.timedelta(days=1),
-
'JWT_AUTH_HEADER_PREFIX': 'JWT',
-
'JWT_RESPONSE_PAYLOAD_HANDLER': 'app.utils.jwt_reponse_revised.jwt_response_payload_handler',
-
}
JWT_RESPONSE_PAYLOAD_HANDLER为当前项目指定文件夹下的函数名
由于源码中会调取此函数作为登录接口的Response
drf源码如下:
-
jwt_response_payload_handler = api_settings.JWT_RESPONSE_PAYLOAD_HANDLER
-
-
-
-
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')
-
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)
jwt_response_payload_handler函数内容:
-
def jwt_response_payload_handler(token,user=None,request=None):
-
"""为返回的结果添加用户相关信息"""
-
return {
-
'result' : {
-
'token':"JWT " token,#与配置保持一致
-
'username':user.loginName,
-
'userid':user.userId
-
}
-
}
实例:
使用:
前端需将Token添加到headers中Authorization
后端验证方式:
-
from rest_framework_jwt.authentication import JSONWebTokenAuthentication
-
class SampleView(mixins.ListModelMixin):
-
queryset = Sample_info.objects.all()
-
serializer_class = SampleSerializers
-
module_name = 'sample'
-
filter_backends = (filters.DjangoFilterBackend, Order,)
-
filter_class = SampleInfoFilter
-
pagination_class = SamplePagination
-
ordering_fields = ('receipt_date',)
-
permission_classes = [IsAuthenticated, ]
-
authentication_classes = [JSONWebTokenAuthentication]#<--------token验证
-
def get(self, request, *args, **kwargs):
-
return self.list(request, *args, **kwargs)
JSONWebTokenAuthentication源码:
-
-
class JSONWebTokenAuthentication(BaseJSONWebTokenAuthentication):
-
"""
-
Clients should authenticate by passing the token key in the "Authorization"
-
HTTP header, prepended with the string specified in the setting
-
`JWT_AUTH_HEADER_PREFIX`. For example:
-
-
Authorization: JWT eyJhbGciOiAiSFMyNTYiLCAidHlwIj
-
"""
-
www_authenticate_realm = 'api'
-
-
def get_jwt_value(self, request):
-
auth = get_authorization_header(request).split()
-
auth_header_prefix = api_settings.JWT_AUTH_HEADER_PREFIX.lower()
-
if not auth:
-
if api_settings.JWT_AUTH_COOKIE:
-
return request.COOKIES.get(api_settings.JWT_AUTH_COOKIE)
-
return None
-
if smart_text(auth[0].lower()) != auth_header_prefix:
-
return None
-
if len(auth) == 1:
-
msg = _('Invalid Authorization header. No credentials provided.')
-
raise exceptions.AuthenticationFailed(msg)
-
elif len(auth) > 2:
-
msg = _('Invalid Authorization header. Credentials string '
-
'should not contain spaces.')
-
raise exceptions.AuthenticationFailed(msg)
-
return auth[1]
-
-
def authenticate_header(self, request):
-
"""
-
Return a string to be used as the value of the `WWW-Authenticate`
-
header in a `401 Unauthenticated` response, or `None` if the
-
authentication scheme should return `403 Permission Denied` responses.
-
"""
-
return '{0} realm="{1}"'.format(api_settings.JWT_AUTH_HEADER_PREFIX, self.www_authenticate_realm)
这篇好文章是转载于:学新通技术网
- 版权申明: 本站部分内容来自互联网,仅供学习及演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,请提供相关证据及您的身份证明,我们将在收到邮件后48小时内删除。
- 本站站名: 学新通技术网
- 本文地址: /boutique/detail/tanhibeijg
系列文章
更多
同类精品
更多
-
photoshop保存的图片太大微信发不了怎么办
PHP中文网 06-15 -
word里面弄一个表格后上面的标题会跑到下面怎么办
PHP中文网 06-20 -
photoshop扩展功能面板显示灰色怎么办
PHP中文网 06-14 -
《学习通》视频自动暂停处理方法
HelloWorld317 07-05 -
TikTok加速器哪个好免费的TK加速器推荐
TK小达人 10-01 -
Android 11 保存文件到外部存储,并分享文件
Luke 10-12 -
微信公众号没有声音提示怎么办
PHP中文网 03-31 -
excel下划线不显示怎么办
PHP中文网 06-23 -
excel打印预览压线压字怎么办
PHP中文网 06-22 -
微信运动停用后别人还能看到步数吗
PHP中文网 07-22