文章目录
- 一、djangorestframework-simplejwt快速使用
- 1.基础使用步骤
- 2.自己配置视图校验访问
- 局部配置认证及权限类
- 全局配置认证及权限类
- 3.关于双token认证问题
- 二、定制返回格式
- 三、多方式登录
一、djangorestframework-simplejwt快速使用
JWT主要用于签发登录接口需要配合认证类 JWT目前有两种
Jtw
和Simplejwt
(jwt比较老了 simple现在比较流行)
1.基础使用步骤
- 安装:建议使用pycharm可以安装到指定解释器
pip install djangorestframework-simplejwt
- simplejwt默认使用
auth_user表签发token
,所以我们直接新建项目后执行迁移命令
-makemigrations
-migrate
- 创建一个超级用户:
createsuperuser
- 签发登录:只需要在路由中配置
(simplejwt帮我们写好了登录接口以及权限类)
路由配置
'导入模块'
from rest_framework_simplejwt.views import token_obtain_pair, token_verify, token_refresh
urlpatterns = [
path('login/', token_obtain_pair), # 登录 签发token
path('verify/', token_verify), # 验证token 是否有效
path('refresh/', token_refresh), # 刷新token
]
settings配置
'注册app'
INSTALLED_APPS = [
...
'rest_framework_simplejwt',
...
]
import datetime
SIMPLE_JWT = {
# token有效时长
'ACCESS_TOKEN_LIFETIME': datetime.timedelta(minutes=30),
# token刷新后的有效时间
'REFRESH_TOKEN_LIFETIME': datetime.timedelta(days=1),
}
此时直接访问即可,它都帮我们写好了,在请求体中携带刚刚创建的超级用户的账号密码就会返回token(因为是simplejwt它是双Token认证)
因为是双token认证,获取到的
access
才是真正使用的token
,而refresh
则是用于更新access
。因为access过期时间很短,过期后就需要重新生成access的token保证token的安全
,所以就需要使用refresh
用来变更新的有效token
变更新的有效token
验证有效期token
2.自己配置视图校验访问
我们定义了一个book视图类,它只允许访问时在请求头里面携带了合法的token值才能通过认证。
路由配置
from rest_framework_simplejwt.views import token_obtain_pair, token_verify
urlpatterns = [
path('login/', token_obtain_pair), # 登录 签发token
path('verify/', token_verify), # 验证token 是否有效
path('refresh/', token_refresh), # 刷新token
]
局部配置认证及权限类
视图配置
from rest_framework.views import APIView
from rest_framework_simplejwt.authentication import JWTAuthentication
from rest_framework.permissions import IsAuthenticated
from rest_framework.response import Response
'局部配置,必须配合权限类'
class BookView(APIView):
'''配置的Jwt认证,但是得在headers添加,如果不添加的话,就不会生效,添加才可生效'''
authentication_classes = [JWTAuthentication] # 登录认证
permission_classes = [IsAuthenticated] # 配置了权限类,没登录的就没有权限访问了
'一旦配置了去认证类和权限类后,refresh的token就无法使用,会显示令牌类型错误,只能使用access的token'
def get(self,reqeust):
return Response({'测试测试'})
'''
这个时候直接访问我们的接口,就会发生错误,"detail":"身份认证信息未提供"
因为我们访问的时候需要带上simplejwt的token
固定格式为:Authorization:Bearer 注意这里哟一个空格,在空格后面填写签发过的token
'''
全局配置认证及权限类
settings中配置
# 全局配置
REST_FRAMEWORK = { '它自己内置的登录是哪怕配置了全局也不会进行认证,源码中进行了禁用'
'DEFAULT_AUTHENTICATION_CLASSES': [
'rest_framework_simplejwt.authentication.JWTAuthentication'
],
'DEFAULT_PERMISSION_CLASSES': [
'rest_framework.permissions.IsAuthenticated',
],
}
携带登录后,服务端响应给我们的token值来访问,token值的开头必须是
Bearer+空格
,因为在源码内部获取校验token值前,会先通过空格进行分隔一下,第一个值是否为Bearer
,如果是的话才会获取空格后面的token值来进行校验,所以我们后续会重写一些方法,不需要遵守一些不必要的规则
注意:只要当前的access的token没过期,而之前签发的access的token和后来刷新签发的access的token都可以使用
3.关于双token认证问题
1)单token
-用户登录后----->签发token---->但是有过期时间
1.设置太短的token过期时间,如:3 minute后就需要重新登录,体验太差,一天啥事不干就重新登录
2.设置太长的token过期时间,如:7 day,7天都不需要登录----->容易被人截获到长时间使用--->不安全
2)双token
-用户登录后---->签发两个token----->目前的verify检验接口,只要是它签发的token,都会认证通过
例如:access:过期时间短 3分钟
例如:refresh:过期时间长 7天
-用户正常用,都会用access,不会用refresh
-access过会有过期了,一旦过期就用不了了---->然后可以通过refresh这个token调用刷新接口,在签发一个access的token
-通过refresh再次签发的token这个过程,是不需要登录的,这对用户是无感知的
-后续再使用access这个token发请求
'认证类:就不能使用refresh的token'
'''
双认证的好处就是,一旦access的token被别人截取到了,拿着模拟发请求,只能在有效时间内使用,
因为access的token很快会过期,这样就保障安全
'''
二、定制返回格式
继承auth_user表完成签发登录,但是它的返回格式太固定了只有Token,但是我们想自定义格式呢?
如:
{
'code': 100,
'msg': '登录成功',
'username': self.user.username,
'token':'fdsafsfsafsadf'
}
1.写个序列化类,重写validate ,返回什么,前端看到什么
from rest_framework_simplejwt.serializers import TokenObtainPairSerializer
class MyTokenObtainPairSerializer(TokenObtainPairSerializer):
@classmethod
def get_token(cls, user):
token = super().get_token(user) # 签发用户
token['name'] = user.username # 往荷载里面添加用户名称
return token
'''重写get_token方法,它返回的token中就是荷载的内容'''
def validate(self, attrs):
old_data = super().validate(attrs)
data = {'code': 100,
'msg': '登录成功',
'username': self.user.username,
'refresh': old_data['refresh'],
'access': old_data['access']
}
return data
2.在settings配置文件中配置
SIMPLE_JWT = {
"TOKEN_OBTAIN_SERIALIZER": "app01.serializer.MyTokenObtainPairSerializer",
}
效果如下