djangorestframework-jwt自带的认证视图进行用户登录验证源代码学习
Django REST framework JWT
djangorestframework-jwt自带的认证视图进行用户登录验证源代码学习
SECRET_KEY = '1)q(f8jrz^edwtr2#h8vj=$u)ip4fx7#h@c41gvxtgc!dj#wkc'
定期动态生成SECRET_KEY
字符串导包 https://blog.csdn.net/chaoguo1234/article/details/81277590
安装配置
安装
pip install djangorestframework-jwt
配置
REST_FRAMEWORK = {
'DEFAULT_AUTHENTICATION_CLASSES': (
'rest_framework_jwt.authentication.JSONWebTokenAuthentication',
'rest_framework.authentication.SessionAuthentication',
'rest_framework.authentication.BasicAuthentication',
),
}
JWT_AUTH = {
'JWT_EXPIRATION_DELTA': datetime.timedelta(days=1),
}
Django REST framework JWT 扩展的说明文档中提供了手动签发JWT的方法
from rest_framework_jwt.settings import api_settings jwt_payload_handler = api_settings.JWT_PAYLOAD_HANDLER
jwt_encode_handler = api_settings.JWT_ENCODE_HANDLER payload = jwt_payload_handler(user)
token = jwt_encode_handler(payload)
从api_settigs下去找,在rest_framework_jwt.settings下面
jwt_payload_handler = api_settings.JWT_PAYLOAD_HANDLER
api_settings = APISettings(USER_SETTINGS, DEFAULTS, IMPORT_STRINGS) # 这三个参数分别对应settings文件下的参数
DEFAULTS 这个参数
DEFAULTS = {
...
'JWT_PAYLOAD_HANDLER':
'rest_framework_jwt.utils.jwt_payload_handler',
...
}
从源码可以看出对应的就是
jwt_payload_handler = api_settings.JWT_PAYLOAD_HANDLER 中的 JWT_PAYLOAD_HANDLER ,key对应的value就是 'rest_framework_jwt.utils.jwt_payload_handler'
而rest_framework_jwt.utils.jwt_payload_handler其实就是一个导包路径
现在从这个路径下去寻找到utils下的jwt_payload_handler函数
def jwt_payload_handler(user):
username_field = get_username_field()
username = get_username(user) warnings.warn(
'The following fields will be removed in the future: '
'`email` and `user_id`. ',
DeprecationWarning
) payload = {
'user_id': user.pk,
'username': username,
'exp': datetime.utcnow() + api_settings.JWT_EXPIRATION_DELTA # JWT_EXPIRATION_DELTA对应的就是在我们配置里指定的过期时间
}
if hasattr(user, 'email'):
payload['email'] = user.email
if isinstance(user.pk, uuid.UUID):
payload['user_id'] = str(user.pk) payload[username_field] = username # Include original issued at time for a brand new token,
# to allow token refresh
if api_settings.JWT_ALLOW_REFRESH:
payload['orig_iat'] = timegm(
datetime.utcnow().utctimetuple()
) if api_settings.JWT_AUDIENCE is not None:
payload['aud'] = api_settings.JWT_AUDIENCE if api_settings.JWT_ISSUER is not None:
payload['iss'] = api_settings.JWT_ISSUER return payload
下面在 jwt_encode_handler = api_settings.JWT_ENCODE_HANDLER 用同样的方法找到JWT_ENCODE_HANDLER对应的value, 也就是导包路径
DEFAULTS = {
...
'JWT_ENCODE_HANDLER':
'rest_framework_jwt.utils.jwt_encode_handler',
...
}
同样根据导包路径寻找
def jwt_encode_handler(payload):
key = api_settings.JWT_PRIVATE_KEY or jwt_get_secret_key(payload)
return jwt.encode(
payload,
key,
api_settings.JWT_ALGORITHM
).decode('utf-8')
生成token的过程

浏览器的保存策略

Django REST framework JWT提供了登录签发JWT的视图,可以直接使用
from rest_framework_jwt.views import obtain_jwt_token urlpatterns = [
url(r'^authorizations/$', obtain_jwt_token),
]
但是默认的返回值仅有token,我们还需在返回值中增加username和user_id。
从 obtain_jwt_token 进去
路由: url(r'^authorizations/, obtain_jwt_token),
obtain_jwt_token来自$PYTHON_ENVTIONS_PATH/site-packages/rest_framework_jwt/views.py的102行和74-80行,代码如下
class ObtainJSONWebToken(JSONWebTokenAPIView):
"""
API View that receives a POST with a user's username and password. Returns a JSON Web Token that can be used for authenticated requests.
"""
serializer_class = JSONWebTokenSerializer """
中间省略部分不相关代码
"""
obtain_jwt_token = ObtainJSONWebToken.as_view()
很明显:这个就是一个登录的视图集
查看下继承的JSONWebTokenAPIView视图
jwt_response_payload_handler = api_settings.JWT_RESPONSE_PAYLOAD_HANDLER ... class JSONWebTokenAPIView(APIView): # 继承至APIView
...
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) # jwt_response_payload_handler 响应对象
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):
"""
Returns the response data for both the login and refresh views.
Override to return a custom response such as including the
serialized representation of the User. Example: def jwt_response_payload_handler(token, user=None, request=None):
return {
'token': token,
'user': UserSerializer(user, context={'request': request}).data
} """
return {
'token': token
}
可以看出,登录后返回的响应对象仅仅有token一个key , 这对于大多数场景来说都是不合适的,所以需要来重写该方法
def jwt_response_payload_handler(token, user=None, request=None):
"""
自定义jwt认证成功返回数据
"""
return {
'token': token,
'user_id': user.id,
'username': user.username
}
因为我们自定义的该方法,所以也需要修改它的导包路径,之前也找到了它的导包路径传入的源码,则在配置文件中进行如下配置:
# JWT
JWT_AUTH = {
'JWT_EXPIRATION_DELTA': datetime.timedelta(days=1),
'JWT_RESPONSE_PAYLOAD_HANDLER': 'users.utils.jwt_response_payload_handler',
}
这样,就实现了修改response响应对象
现在看完了继承的类视图,下面来看下序列化器:
在刚刚的源码中能看得到指定的序列化器就是 serializer_class = JSONWebTokenSerializer
既然指定了serializer_class = JSONWebTokenSerializer 说明是使用了DRF框架做验证, 那么验证用户登录时传输的参数的代码就是在序列化器类的代码中
序列化器类来自于$PYTHON_ENVTIONS_PATH/site-packages/rest_framework_jwt/serializers.py22-69行, 代码如下:
class JSONWebTokenSerializer(Serializer):
"""
省略部分代码
"""
def validate(self, attrs):
# 获取参数: 用户登录名称 + 密码
credentials = {
self.username_field: attrs.get(self.username_field),
'password': attrs.get('password')
} if all(credentials.values()):
# 用户登录时传入的参数完整, 则验证用户并获取用户对象
# 获取用户对象的代码在下面djangorestframework-jwt自带的认证视图进行用户登录验证源代码学习的更多相关文章
- Django-REST-Framework JWT 实现SSO认证(上)
一.什么是Django-REST-Framework? Django-REST-framework 是基于Django框架的一个web RESTful风格开发的框架,它可以实现API接口的快速开发,但 ...
- Django-REST-Framework JWT 实现SSO认证(下)
在上一篇博客中,我已经对JSON Web 认证做了简单的解释,这篇博客是续篇,若不了解,请看上一篇博客:https://www.cnblogs.com/yushenglin/p/10863184.ht ...
- day77:luffy:导航栏的实现&DjangoRestFramework JWT&多条件登录
目录 1.导航栏的实现 2.登录前戏:用户表初始化 3.DjangoRestFramework JWT 4.多条件登录 5.登录状态的判断和退出登录 1.导航栏的实现 1.设计导航栏的model模型类 ...
- Django之自带的认证系统 auth模块
01-Django自带的用户认证 我们在开发一个网站的时候,无可避免的需要设计实现网站的用户系统.此时我们需要实现包括用户注册.用户登录.用户认证.注销.修改密码等功能,这还真是个麻烦的事情呢. Dj ...
- spring jwt springboot RESTful API认证方式
RESTful API认证方式 一般来讲,对于RESTful API都会有认证(Authentication)和授权(Authorization)过程,保证API的安全性. Authenticatio ...
- SpringBoot系列 - 集成JWT实现接口权限认证
会飞的污熊 2018-01-22 16173 阅读 spring jwt springboot RESTful API认证方式 一般来讲,对于RESTful API都会有认证(Authenticati ...
- 基于JWT的token身份认证方案
一.使用JSON Web Token的好处? 1.性能问题. JWT方式将用户状态分散到了客户端中,相比于session,可以明显减轻服务端的内存压力. Session方式存储用户id的最大弊病在于S ...
- SpringBoot集成JWT 实现接口权限认证
JWT介绍 Json web token (JWT), 是为了在网络应用环境间传递声明而执行的一种基于JSON的开放标准((RFC 7519).该token被设计为紧凑且安全的, 特别适用于分布式站点 ...
- .net core webapi jwt 更为清爽的认证
原文:.net core webapi jwt 更为清爽的认证 我的方式非主流,控制却可以更加灵活,喜欢的朋友,不妨花一点时间学习一下 jwt认证分为两部分,第一部分是加密解密,第二部分是灵活的应用于 ...
随机推荐
- JSF生命周期&Facelets的生命周期
1.JSF生命周期 1)恢复视图(Restore View) 视图表示组成特定页面的所有组件.它被保存在 客户端(通常存储在隐藏字段中)或服务器中(通常在会话中).根据请求访问的视图ID(页面地址), ...
- The listener supports no services
问题描述 sql> lsnrctl start 提示: The listener supports no services The command completed successfully ...
- GitHub 优秀的项目地址
Type LibDescription LibLocation Android SlidingMenu https://github.com/jfeinstein10/SlidingMenu ...
- Python 配置 selenium 模拟浏览器环境,带下载链接
使用浏览器渲染引擎.直接用浏览器在显示网页时解析HTML,应用CSS样式并执行JavaScript的语句. 这方法在爬虫过程中会打开一个浏览器,加载该网页,自动操作浏览器浏览各个网页,顺便把数据抓下来 ...
- Linux可以生产uImage
默认kernel只生产Image和zImage,若想让kernel生产uImage,需要用到mkimage,这个是uboot可以提供的,位于uboot/tool/目录下,将其加入到环境变量即可.
- creator NDK_PROJECT_PATH=null
NDK_PROJECT_PATH=null 其实不是一个错误= =,少年,不要纠结于此了. 主要问题在于这一句: process_begin: CreateProcess(NULL, E:/Andro ...
- javascript 操作节点的属性
使用层次关系访问节点 parentNode:返回节点的父节点 childNodes:返回子节点集合,childNodes[i] firstChild:返回节点的第一个子节点,最普遍的用法是访问该元素的 ...
- BigData_Jia
#include <stdio.h> #include <string.h> #define MaxSize 10000 int n1, n2, i, k, times; ch ...
- Go实例解析
Go语言包的加载顺序如图 可以通过如下实例详细了解 代码来源于<Go实战> 代码地址:https://github.com/goinaction/code 项目代码结构 程序架构 首先分析 ...
- 汇编实验1(又是作业emm)
实验任务:学会使用debug 1.使用Debug,将程序段写入内存: 机器码: b8 20 4e 05 16 14 bb 00 20 01 d8 89 c3 01 d8 b8 1a 00 bb 26 ...