本文主要是介绍drf 自定义User表,签发token 自定义认证类 simpleui的使用,对大家解决编程问题具有一定的参考价值,需要的程序猿们随着小编来一起学习吧!
内容详细
1 自定义User表,签发token
# 如果项目中的User表使用auth的user表,使用快速签发token即可
# 如果自定义User表,签发token,需要手动签发---》自己写
1.1 普通写法
from rest_framework.views import APIView
# class UserView(APIView):
# 自动生成路由,
from rest_framework.viewsets import ViewSetMixin
from rest_framework.decorators import action
from rest_framework.generics import GenericAPIView
from .models import UserInfo
from .serializer import UserInfoSerializer
from rest_framework.response import Response
from rest_framework_jwt.settings import api_settings
jwt_payload_handler = api_settings.JWT_PAYLOAD_HANDLER
jwt_encode_handler = api_settings.JWT_ENCODE_HANDLER
# /user/login/--->post请求
# class UserView(ViewSetMixin, APIView):
# @action(methods=['POST'], detail=False)
# def login(self, request):
# res_dic = {'code': 100, 'msg': '成功'}
# username = request.data.get('username')
# password = request.data.get('password')
# user = UserInfo.objects.filter(username=username, password=password).first()
# if user: # 登陆成功
# # 签发token?如何签发?--》去jwt源码中扣
# payload = jwt_payload_handler(user) # 得到荷载--》字典
# print(payload)
# token = jwt_encode_handler(payload) # 通过荷载得到token串
# res_dic['token'] = token
# res_dic['username'] = user.username
# return Response(res_dic)
# else:
# res_dic['code'] = 101
# res_dic['msg'] = '用户名或密码错误'
# return Response(res_dic)
1.2 逻辑写在序列化类中
# 换种写法,写上面的登录,所有校验规则,写在序列化类中---》这种用的多
class UserView(ViewSetMixin, APIView):
@action(methods=['POST'], detail=False)
def login(self, request):
res_dic = {'code': 100, 'msg': '成功'}
ser = UserInfoSerializer(data=request.data,context={'request':request})
if ser.is_valid(): # 这句话会走:字段自己的校验规则,局部钩子,全局钩子
token = ser.context.get('token')
username = ser.context.get('username')
# token = ser.token
# username = ser.username
res_dic['token'] = token
res_dic['username'] = username
else:
res_dic['code'] = 101
res_dic['msg'] = ser.errors
return Response(res_dic)
class UserInfoSerializer(serializers.ModelSerializer):
class Meta:
model = UserInfo
fields = ['username', 'password'] # 根据表模型中写的,字段自己有校验规则
def validate(self, attrs):
# 打印请求方式?
print(self.context.get('request').method)
# 签发token逻辑,签发生成token,放到ser.context字典中
username = attrs.get('username')
password = attrs.get('password')
user = UserInfo.objects.filter(username=username, password=password).first()
if user: # 登陆成功
payload = jwt_payload_handler(user) # 得到荷载--》字典
token = jwt_encode_handler(payload) # 通过荷载得到token串
# serializer和视图类沟通的桥梁
self.context['token'] = token
self.context['username'] = user.username
# self.token=token
# self.username=username
else:
raise ValidationError('用户名或密码错误')
return attrs
2 自定义认证类
from rest_framework.authentication import BaseAuthentication
from rest_framework_jwt.settings import api_settings
from rest_framework.exceptions import AuthenticationFailed
import jwt
# from django.utils.translation import ugettext as _
from .models import UserInfo
jwt_decode_handler = api_settings.JWT_DECODE_HANDLER
class JWTAuthentication(BaseAuthentication):
def authenticate(self, request):
# 第一步:取出传入的token--》从哪去?--》咱们定的:请求地址?请求头?
# token=request.query_params.get('token')# 请求地址?
# http请求头中的数据,在META中,统一变成 HTTP_请求头的key大写
jwt_value=request.META.get('HTTP_TOKEN')
if jwt_value:
# 验证token:是否过期,是否被篡改--》去源码扣
try:
payload = jwt_decode_handler(jwt_value)
except jwt.ExpiredSignature:
msg = '签名过期'
raise AuthenticationFailed(msg)
except jwt.DecodeError:
msg = '签名被篡改'
raise AuthenticationFailed(msg)
except jwt.InvalidTokenError:
raise AuthenticationFailed('未知错误')
# 通过payload获得当前登录用户
user = UserInfo.objects.filter(pk=payload['user_id']).first()
return (user, jwt_value)
else:
raise AuthenticationFailed('您没有携带token')
3 simpleui的使用
# django-admin混合开发--》后台管理---》美化--》simpleui
# 使用步骤:
-安装:pip3 install django-simpleui
-注册app
INSTALLED_APPS = [
'simpleui',
]
-定制左侧菜单
SIMPLEUI_CONFIG = {
'system_keep': False,
'menu_display': ['监控大屏','应用1', '权限认证', '测试', '动态菜单测试'], # 开启排序和过滤功能, 不填此字段为默认排序和全部显示, 空列表[] 为全部不显示.
'dynamic': True, # 设置是否开启动态菜单, 默认为False. 如果开启, 则会在每次用户登陆时动态展示菜单内容
'menus': [
{
'name': '监控大屏',
'icon': 'fas fa-code',
'url': '/index/'
},
{
'app': 'app01',
'name': '应用1',
'icon': 'fas fa-user-shield',
'models': [
{
'name': '图书',
'icon': 'fa fa-user',
'url': 'app01/book/'
},
{
'name': '用户',
'icon': 'fa fa-user',
'url': 'app01/userinfo/'
}
]
},
{
'app': 'auth',
'name': '权限认证',
'icon': 'fas fa-user-shield',
'models': [
{
'name': '用户',
'icon': 'fa fa-user',
'url': 'auth/user/'
},
{
'name': '用户组',
'icon': 'fa fa-user',
'url': 'auth/group/'
}
]
},
{
# 自2021.02.01+ 支持多级菜单,models 为子菜单名
'name': '测试',
'icon': 'fa fa-file',
# 二级菜单
'models': [{
'name': 'Baidu',
'icon': 'far fa-surprise',
# 第三级菜单 ,
'models': [
{
'name': '爱奇艺',
'url': 'https://www.iqiyi.com/dianshiju/'
# 第四级就不支持了,element只支持了3级
}, {
'name': '百度问答',
'icon': 'far fa-surprise',
'url': 'https://zhidao.baidu.com/'
}
]
}, {
'name': '内网穿透',
'url': 'https://www.wezoz.com',
'icon': 'fab fa-github'
}]
},
{
'name': '动态菜单测试',
'icon': 'fa fa-desktop',
'models': [{
'name': time.time(),
'url': 'http://baidu.com',
'icon': 'far fa-surprise'
}]
}
]
}
-自带权限
-自定义左侧菜单的页面显示
-通过混合开发,编写路径,配置到上面即可
-更多操作见官方
这篇关于drf 自定义User表,签发token 自定义认证类 simpleui的使用的文章就介绍到这儿,希望我们推荐的文章对大家有所帮助,也希望大家多多支持为之网!