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自带的认证视图进行用户登录验证源代码学习的更多相关文章

  1. Django-REST-Framework JWT 实现SSO认证(上)

    一.什么是Django-REST-Framework? Django-REST-framework 是基于Django框架的一个web RESTful风格开发的框架,它可以实现API接口的快速开发,但 ...

  2. Django-REST-Framework JWT 实现SSO认证(下)

    在上一篇博客中,我已经对JSON Web 认证做了简单的解释,这篇博客是续篇,若不了解,请看上一篇博客:https://www.cnblogs.com/yushenglin/p/10863184.ht ...

  3. day77:luffy:导航栏的实现&DjangoRestFramework JWT&多条件登录

    目录 1.导航栏的实现 2.登录前戏:用户表初始化 3.DjangoRestFramework JWT 4.多条件登录 5.登录状态的判断和退出登录 1.导航栏的实现 1.设计导航栏的model模型类 ...

  4. Django之自带的认证系统 auth模块

    01-Django自带的用户认证 我们在开发一个网站的时候,无可避免的需要设计实现网站的用户系统.此时我们需要实现包括用户注册.用户登录.用户认证.注销.修改密码等功能,这还真是个麻烦的事情呢. Dj ...

  5. spring jwt springboot RESTful API认证方式

    RESTful API认证方式 一般来讲,对于RESTful API都会有认证(Authentication)和授权(Authorization)过程,保证API的安全性. Authenticatio ...

  6. SpringBoot系列 - 集成JWT实现接口权限认证

    会飞的污熊 2018-01-22 16173 阅读 spring jwt springboot RESTful API认证方式 一般来讲,对于RESTful API都会有认证(Authenticati ...

  7. 基于JWT的token身份认证方案

    一.使用JSON Web Token的好处? 1.性能问题. JWT方式将用户状态分散到了客户端中,相比于session,可以明显减轻服务端的内存压力. Session方式存储用户id的最大弊病在于S ...

  8. SpringBoot集成JWT 实现接口权限认证

    JWT介绍 Json web token (JWT), 是为了在网络应用环境间传递声明而执行的一种基于JSON的开放标准((RFC 7519).该token被设计为紧凑且安全的, 特别适用于分布式站点 ...

  9. .net core webapi jwt 更为清爽的认证

    原文:.net core webapi jwt 更为清爽的认证 我的方式非主流,控制却可以更加灵活,喜欢的朋友,不妨花一点时间学习一下 jwt认证分为两部分,第一部分是加密解密,第二部分是灵活的应用于 ...

随机推荐

  1. spring3-struts2整合

    spring  负责对象创建 struts   用Action处理请求 说明: spring版本:spring-framework-3.2.5.RELEASE struts版本:struts-2.3. ...

  2. 2.GUI控件的使用 --《UNITY 3D 游戏开发》笔记

    1.Label 控件 编写脚本文件,直接绑定在main camera上 public class labelScript : MonoBehaviour { //设定一个值来接收外部赋值的字符串 pu ...

  3. EBS查询在线用户

    转自:https://www.cnblogs.com/benio/archive/2011/03/10/1979417.html SELECT u.user_name, app.application ...

  4. 火狐firebug和firepath插件安装方法(最新)

    火狐浏览器最近下掉了firebug和firepath插件,用户即使下载了火狐55以下的版本,也无法查找到这两个插件. 因此,可以用以下方法来获取这两个插件. 1.下载火狐55以内版本安装包,安装时迅速 ...

  5. MySQL常用命令(数据库,表相关的命令)

    数据库相关命令 显示数据库列表 mysql> SHOW  DATABASES; 创建数据库 mysql> CREATE  DATABASE  库名; 如下,创建一个名为crashcours ...

  6. 剑指offer 6.查找和排序 旋转数组的最小数字

    题目描述 把一个数组最开始的若干个元素搬到数组的末尾,我们称之为数组的旋转. 输入一个非减排序的数组的一个旋转,输出旋转数组的最小元素. 例如数组{3,4,5,1,2}为{1,2,3,4,5}的一个旋 ...

  7. Day14全局变量与局部变量

    列表的所有方法都可以用,如remove  clear 为了避免容易出错,全局变量名用大写,局部变量名用小写  nonlocal指上一级的name

  8. java读取json文件进行解析,String转json对象

    String jsonFilePath = "C:/a.json"; File file = new File(jsonFilePath ); String input = Fil ...

  9. ISE_pll_ip的建立

    创建clk的ip核以及设置PLL的时钟输出 原理:外部晶振输入50M的频率,由ip核输出想要的频率 1.新建工程model再在"芯片"名称上建立clk的ip核 2.设置输入写为50 ...

  10. 【rabbitmq】rabbitmq集群环境搭建

    安装rabbitmq-server 总共有3台虚拟机,都安装有rabbitmq服务,安装过程可参考: [rabbitmq]Centos7 下安装rabbitmq 创建用户和vhost 说明: 此步骤不 ...