DRF-JWT

一、JWT

  • JWT全称: json web token,

  • 作用:将原始的数据json加密成字符串,通过后台将加密的字符串给前台存储(token)

  • 格式:三段式,头.载荷.签名 , 头和载荷都是采用base34可逆加密,签名采用md5不可逆加密

    • 头(基础信息,也可以为空):加密方式、公司信息、项目中信息....
    • 载荷(核心信息): 用户信息、过期时间...
    • 签名(安全保障): 头加密结果+载荷加密结果+服务器秘钥的md5加密的结果
    • 注意:后台一定要保障服务器秘钥的安全,他是jwt唯一安全保障,后台签发token -> 前台存储 -> 发送需要认证的请求带着token -> 后台校验得到合法的用户
  • jwt认证优点:

    • 后台不需要存储token,只需要存储签发与校验tokne的算法,效率远远大于后台存储和取出完成token的校验
    • jwt算法认证,更适合服务器集群的部署
  • 采用drf-jwt框架,后期任务主需要书写登录,drf-jwt只完成了账号密码登录,我们还需要手机登录,邮箱登录,不需要重写认证类,因为认证规则已经完成且固定不变,变得只有认证字符串的前缀,前缀可以在配置文件中配置

二、jwt模块安装

# 安装
>:pip install djangorestframework-jwt
# 模块
rest_framework_jwt

三、前后端分离模式下信息交互规则

  1. 任何人都可以直接访问的接口

    请求不论是get、还是post请求方式,不需要任何的校验

  2. 必须登录后才能访问接口

    任何请求方式都进行限制,请求中必须在请求头中携带认证信息 - authorization

  3. 前台认证信息获取只能通过登录接口

    前台提供账号和密码等信息,到后台进行校验返回认证信息token加密字符串

  4. 前台如何完成注销

    前台登录成功一般在cookie中保存认证信息token,登录注销就是前台主动清除保存的token加密字符串信息

四、jwt模块使用

4.1全局配置

# rest_framework全局配置 认证
'DEFAULT_AUTHENTICATION_CLASSES': [
'rest_framework.authentication.SessionAuthentication',
'rest_framework.authentication.BasicAuthentication'
], # jwt认证类配置
'DEFAULT_AUTHENTICATION_CLASSES': [
'rest_framework_jwt.authentication.JSONWebTokenAuthentication',
], # 局部禁用
authentication_classes = [] # # 局部启用
from user.authentications import JSONWebTokenAuthentication
authentication_classes = [JSONWebTokenAuthentication]

只需将rest_framework全局配置认证改成JWT认证

4.2 token过期时间配置

# drf-jwt配置
import datetime
JWT_AUTH = {
# 过期时间,生成的took七天之后不能使用
'JWT_EXPIRATION_DELTA': datetime.timedelta(days=7),
# 刷新时间 之后的token时间值
# 'JWT_ALLOW_REFRESH': True,
'JWT_REFRESH_EXPIRATION_DELTA': datetime.timedelta(days=7),
# 请求头携带的参数
'JWT_AUTH_HEADER_PREFIX': 'JWT',
}

4.3JWT认证使用

from django.conf.urls import url
from . import views
from rest_framework_jwt.views import ObtainJSONWebToken,obtain_jwt_token,verify_jwt_token,refresh_jwt_token
urlpatterns = [
# url(r'^admin/', admin.site.urls),
url(r'^test/', views.TestAPIview.as_view()),
url(r'^user/', views.UserListAPIView.as_view()),
url(r'^login/', views.LoginAPIView.as_view()), # jwt认证
# url(r'^jwt/login/', views.JwtLoginAPIView.as_view()),
url(r'^jwt/login/$', views.JwtLoginAPIView.as_view()),
url(r'^jwt/center/$', views.JwtUserCenterAPIView.as_view()), ]

1.多方登录认证

# url.py
url(r'^login/$', views.LoginAPIView.as_view()),
url(r'^user/center/$', views.UserCenterAPIView.as_view()),
# 1. 反序列化类.py
from rest_framework.serializers import ModelSerializer, CharField, ValidationError, SerializerMethodField
from . import models
from django.contrib.auth import authenticate
import re from rest_framework_jwt.serializers import jwt_payload_handler, jwt_encode_handler
class LoginSerializer(ModelSerializer):
username = CharField(write_only=True)
password = CharField(write_only=True)
class Meta:
model = models.User
fields = ('username', 'password')
# 在全局钩子中签发token
def validate(self, attrs):
# user = authenticate(**attrs)V
# 账号密码登录 => 多方式登录
user = self._many_method_login(**attrs)
# 签发token,并将user和token存放到序列化对象中
payload = jwt_payload_handler(user) # 获取用户信息
token = jwt_encode_handler(payload) # 生成token
self.user = user
self.token = token
return attrs # 多方式登录
def _many_method_login(self, **attrs):
username = attrs.get('username')
password = attrs.get('password')
if re.match(r'.*@.*', username):
user = models.User.objects.filter(email=username).first() # type: models.User
elif re.match(r'^1[3-9][0-9]{9}$', username):
user = models.User.objects.filter(mobile=username).first()
else:
user = models.User.objects.filter(username=username).first() if not user:
raise ValidationError({'username': '账号有误'}) if not user.check_password(password):
raise ValidationError({'password': '密码有误'}) return user # 2.view.py
from rest_framework.views import APIView
from . import models, serializers
from utils.response import APIResponse
class LoginAPIView(APIView):
authentication_classes = []
permission_classes = []
def post(self, request, *args, **kwargs):
serializer = serializers.LoginSerializer(data=request.data)
serializer.is_valid(raise_exception=True)
return APIResponse(msg='login success', data={
'username': serializer.user.username,
'token': serializer.token
})

4.2 获取用户信息

# 序列化类.py
class JwtUserModelSerializer(serializers.ModelSerializer):
password = serializers.SerializerMethodField() def get_password(self, obj):
return "#########" class Meta:
model = models.User
fields = ('username', 'password', 'email', 'first_name', 'last_name')
# view.py
class JwtUserCenterAPIView(APIView):
# 权限认证
permission_classes = [IsAdminUser] def get(self, request, *args, **kwargs):
user = request.user
serializer_obj = serializers.JwtUserModelSerializer(user) return APIResponse(data=serializer_obj.data)

五、总结

jwt模块使用:

  1. 使用jwt模块认证的时候需要在全局配置认证使用的是jwt的认证模块
  2. 可以设置token的过期时间,在setting.py中配置

DRF-JWT的更多相关文章

  1. DRF JWT的用法 & Django的自定义认证类 & DRF 缓存

    JWT 相关信息可参考: https://www.jianshu.com/p/576dbf44b2ae DRF JWT 的使用方法: 1. 安装 DRF JWT # pip install djang ...

  2. DRF JWT认证(一)

    为什么要使用JWT认证?构成和原理又是什么?怎么还有Base64的事?我都写了

  3. DRF JWT认证(二)

    快速上手JWT签发token和认证,有这一篇就够了,DRF自带的和自定义的都帮你总结好了,拿去用~

  4. django drf JWT

    建议使用djangorestframework-jwt或者djangorestframework_simplejwt,文档为 https://github.com/GetBlimp/django-re ...

  5. 9) drf JWT 认证 签发与校验token 多方式登陆 自定义认证规则反爬 admin密文显示

    一 .认证方法比较 1.认证规则图 django 前后端不分离 csrf认证 drf 前后端分离 禁用csrf 2. 认证规则演变图 数据库session认证:低效 缓存认证:高效 jwt认证:高效 ...

  6. drf JWT认证模块与自定制

    JWT模块 在djangorestframework中,有一款扩展模块可用于做JWT认证,使用如下命令进行安装: pip install djangorestframework-jwt 现在,就让我们 ...

  7. drf☞jwt自动签发与手动签发

    目录 一.自动签发 二.手动签发 一.自动签发 urls from rest_framework_jwt.views import obtain_jwt_token # 使用jwt自带的登录视图 ur ...

  8. django drf框架中的user验证以及JWT拓展的介绍

    登录注册是几乎所有网站都需要去做的接口,而说到登录,自然也就涉及到验证以及用户登录状态保存,最近用DRF在做的一个关于网上商城的项目中,引入了一个拓展DRF JWT,专门用于做验证和用户状态保存.这个 ...

  9. drf框架 - JWT认证插件

    JWT认证 JWT认证方式与其他认证方式对比: 优点 1) 服务器不要存储token,token交给每一个客户端自己存储,服务器压力小 2)服务器存储的是 签发和校验token 两段算法,签发认证的效 ...

  10. DRF之三大认证

    一.用户认证Authorticatons 1.源码解析 第一步. 找入口 def dispatch(self, request, *args, **kwargs): # 1.首先我们进入的是APIVi ...

随机推荐

  1. 英语语法 - the + 形容词 的意义

    1,表示一类人  (复数) the young 青年 the old 老年the poor 穷人 the rich 富人the sick 病人 The old need care more than ...

  2. 160-PHP 文本替换函数str_replace(一)

    <?php $str='Hello world!'; //定义源字符串 $search='o'; //定义将被替换的字符 $replace='O'; //定义替换的字符串 $res=str_re ...

  3. Java中如何序列化一个对象(转)

    转自:http://blog.csdn.net/chx10051413/article/details/40784667 http://www.cnblogs.com/baoendemao/p/380 ...

  4. ACM-AK吧!少年

    题目描述:AK吧!少年 AK is an ACM competition finished all of the problems. AC This problem is one of the ste ...

  5. spring源码 继承AttributeAccessor的BeanDefinition接口

    /** * A BeanDefinition describes a bean instance, which has property values, * constructor argument ...

  6. 【Python】【Django】查询所有学生信息

    要做到以下效果: 改代码后效果: 从0开始顺序计数: 倒叙计数到0

  7. 利用标签导出Word文档

    1 using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; us ...

  8. Android之Intent相关知识

    什么是Intent?Intent的作用? Intent是一个消息传递对象,我们可以通过它来启动其他组件或者在组件之间传递数据. 通过Intent启动其他组件 Intent可以用来启动Activity, ...

  9. HDU 1576:A/B

    A/B Time Limit: 1000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Total Submis ...

  10. vs使用opencv总提示igdrclneo64.dll异常.exe: 0xC0000005:的解决方法

    最近项目中要使用opencv库,搭建好环境,使用接口的时候,总提示 igdrclneo64.dll报错崩溃,一直怀疑是自己程序的问题,后面经过一系列的查资料才解决 解决办法: 本地环境:vs2015+ ...