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. C++实验五

    #include <iostream> #include <vector> #include <string> using namespace std; // 函数 ...

  2. 作业二:构建swap函数

    一.swap代码 #include<stdio.h> int main() //主函数部分 { void swap(int *m,int *n); int a,b; int *p1,*p2 ...

  3. the status bar issue of react-native Modal on Android ( RN v0.57.0)

    Problem: When use Modal in react-native, the status bar is not included if you make a full-screen ma ...

  4. wps excel

    ET.Application etApp;ET.workbook etbook;ET.Worksheet etsheet ;ET.Range etrange;//获取工作表表格etApp = new  ...

  5. svn的分支与合并

    作者:fbysss msn:jameslastchina@hotmail.com  blog:blog.csdn.net/fbysss 声明:本文由fbysss原创,转载请注明出处 关键字:svn分支 ...

  6. pymongo中的连接操作:Connection()与MongoClient()

    class MongoClient(pymongo.common.BaseObject) Connection to MongoDB. Method resolution order: MongoCl ...

  7. LOJ 2550 「JSOI2018」机器人——找规律+DP

    题目:https://loj.ac/problem/2550 只会写20分的搜索…… #include<cstdio> #include<cstring> #include&l ...

  8. C#使用CH341 SPI模块读写SD卡

    SD卡相关CMD命令 ;//卡复位 ; ;//命令9 ,读CSD数据 ;//命令10,读CID数据 ;//命令12,停止数据传输 ;//命令16,设置SectorSize 应返回0x00 ;//命令1 ...

  9. Centos7下安装pptp客户端

    1.使用yum安装ppp和pptp yum install ppp pptp 2.配置pptp pptpsetup --create vpn连接名称(自定义) --server VPN服务器IP -- ...

  10. php 学习资料

    http://blog.csdn.net/woshihaiyong168/article/details/52846205  --队列基本原理的认识