完整的代码
  https://gitee.com/mom925/django-system

使用jwt实现用户认证

pip install djangorestframework-simplejwt

重新定义一下User类
class Users(AbstractUser):
class Meta:
db_table = "system_users"
verbose_name = "用户表"
verbose_name_plural = verbose_name
ordering = ("-create_datetime",)
GENDER_CHOICES = (
(0, "未知"),
(1, "男"),
(2, "女"),
)
username = models.CharField(max_length=150, unique=True, db_index=True, verbose_name="用户账号", help_text="用户账号")
nickname = models.CharField(max_length=50, verbose_name="昵称", null=True, blank=True, help_text="昵称")
email = models.EmailField(max_length=255, verbose_name="邮箱", null=True, blank=True, help_text="邮箱")
mobile = models.CharField(max_length=255, verbose_name="电话", null=True, blank=True, help_text="电话")
avatar = models.CharField(max_length=255, verbose_name="头像", null=True, blank=True, help_text="头像")
gender = models.IntegerField(choices=GENDER_CHOICES, default=0, verbose_name="性别", null=True, blank=True, help_text="性别")
create_datetime = models.DateTimeField(auto_now_add=True, verbose_name="创建时间", null=True, blank=True, help_text="创建时间")
role = models.ManyToManyField(to="Role", blank=True, verbose_name="关联角色", db_constraint=False, help_text="关联角色")
并在 settings.py 加入

AUTH_USER_MODEL = 'system.Users'
USERNAME_FIELD = "username"

设置全局的默认认证和权限 在settings.py 配置 REST_FRAMEWORK
  
REST_FRAMEWORK = {
"DEFAULT_PERMISSION_CLASSES": [
"rest_framework.permissions.IsAuthenticated", # 只有经过身份认证确定用户身份才能访问
],
'DEFAULT_AUTHENTICATION_CLASSES': [
"rest_framework_simplejwt.authentication.JWTAuthentication",
],
}
接下来需要获取用户的token

先配置获取token和刷新token的路由

path('login/', views.LoginView.as_view(), name='登录'),
path('refresh/', views.CustomTokenRefreshView.as_view(), name='刷新token'),
接下来重写一下登录的序列器
class LoginSerializer(TokenObtainPairSerializer):
"""
登录的序列化器:
""" class Meta:
model = Users
fields = "__all__"
read_only_fields = ["id"] def validate(self, attrs):
if settings.AUTH_CAPTCHA:
captcha = self.initial_data.get("captcha", None)
captchaKey = self.initial_data.get("captchaKey", None)
if captcha is None:
raise CustomValidationError(detail='验证码不能为空')
cache_captcha = cache.get('captcha_' + captchaKey)
if cache_captcha is None:
raise CustomValidationError(detail='验证码过期')
if str(captcha) != str(cache_captcha):
raise CustomValidationError(detail='验证码不正确')
cache.delete('captcha_' + captchaKey)
data = super().validate(attrs)
data["user_name"] = self.user.username
data["user_id"] = self.user.id
data['avatar_url'] = get_avatar_url(self.user.avatar) if self.user.avatar else self.user.avatar
request = self.context.get("request")
request.user = self.user
request_save_log(request, {'action': '用户登录', 'describe': '用户账号密码登录'})
return {"code": 1, "msg": "success", "data": data}
登录视图
class LoginView(TokenObtainPairView):
"""
tags:
登录
"""
serializer_class = LoginSerializer
authentication_classes = []
permission_classes = []
刷新token视图
class CustomTokenRefreshView(TokenRefreshView):
"""
tags:
刷新token
"""
def post(self, request, *args, **kwargs):
refresh_token = request.data.get("refresh")
try:
token = RefreshToken(refresh_token)
data = {
"access": str(token.access_token),
"refresh": str(token)
}
except:
return ErrorResponse(msg='error')
return SuccessResponse(data=data)
自定义一下后台的认证,使用自定义后台认证需要在settings.py 中加入 AUTHENTICATION_BACKENDS = ["utils.backend.CustomBackend"]
class CustomBackend(ModelBackend):
"""
Django原生认证方式
""" def authenticate(self, request, username=None, password=None, **kwargs): if username is None:
username = kwargs.get(UserModel.USERNAME_FIELD)
if username is None or password is None:
return
try:
user = UserModel._default_manager.get_by_natural_key(username)
except Exception:
pass
# print(traceback.format_exc())
# except UserModel.DoesNotExist:
# # Run the default password hasher once to reduce the timing
# # difference between an existing and a nonexistent user (#20760).
# UserModel().set_password(password)
else:
if user.check_password(password):
if self.user_can_authenticate(user):
return user
else:
raise CustomValidationError("当前用户已被禁用,请联系客服或管理员!")

登录成功

自定义权限

定义权限和角色模型
class Role(models.Model):
class Meta:
db_table = "system_role"
verbose_name = "角色表"
verbose_name_plural = verbose_name
ordering = ("sort",)
name = models.CharField(max_length=64, verbose_name="角色名称", help_text="角色名称")
sort = models.IntegerField(default=1, verbose_name="角色顺序", help_text="角色顺序")
status = models.BooleanField(default=True, verbose_name="角色状态", help_text="角色状态")
admin = models.BooleanField(default=False, verbose_name="是否为admin", help_text="是否为admin")
remark = models.TextField(verbose_name="备注", help_text="备注", null=True, blank=True)
permission = models.ManyToManyField(to="Permission", verbose_name="关联权限", db_constraint=False, help_text="关联权限") class Permission(models.Model):
class Meta:
db_table = "system_permission"
verbose_name = "权限表"
verbose_name_plural = verbose_name
ordering = ("-value",) METHOD_CHOICES = (
(0, "GET"),
(1, "POST"),
(2, "PUT"),
(3, "DELETE"),
)
name = models.CharField(max_length=64, verbose_name="名称", help_text="名称")
value = models.CharField(max_length=64, verbose_name="权限值", help_text="权限值")
api = models.CharField(max_length=200, verbose_name="接口地址", help_text="接口地址")
method = models.IntegerField(default=0, verbose_name="接口请求方法", null=True, blank=True, help_text="接口请求方法") class ApiWhiteList(models.Model):
class Meta:
db_table = "api_white_list"
verbose_name = "接口白名单"
verbose_name_plural = verbose_name
ordering = ("-create_datetime",) METHOD_CHOICES = (
(0, "GET"),
(1, "POST"),
(2, "PUT"),
(3, "DELETE"),
)
url = models.CharField(max_length=200, help_text="url地址", verbose_name="url") method = models.IntegerField(default=0, verbose_name="接口请求方法", null=True, blank=True, help_text="接口请求方法")
enable_datasource = models.BooleanField(default=True, verbose_name="激活数据权限", help_text="激活数据权限", blank=True)
create_datetime = models.DateTimeField(auto_now_add=True, verbose_name="创建时间", null=True, blank=True, help_text="创建时间")
自定义的权限可以继承 BasePermission 自己定义其中的逻辑,例如:

  
class CustomPermission(BasePermission):
"""自定义权限""" def has_permission(self, request, view):
if isinstance(request.user, AnonymousUser):
return False
# 判断是否是超级管理员
if request.user.is_superuser:
return True
else:
api = request.path # 当前请求接口
method = request.method # 当前请求方法
methodList = ['GET', 'POST', 'PUT', 'DELETE', 'OPTIONS', 'PATCH']
method = methodList.index(method)
# ***接口白名单***
api_white_list = ApiWhiteList.objects.filter(enable_datasource=True).values(permission__api=F('url'), permission__method=F('method'))
api_white_list = [
str(item.get('permission__api').replace('{id}', '([a-zA-Z0-9-]+)')) + ":" + str(
methodList.index(item.get('permission__method', 'GET'))) + '$' for item in api_white_list if item.get('permission__api')]
# ********#
if not hasattr(request.user, "role"):
return False
userApiList = request.user.role.values('permission__api', 'permission__method') # 获取当前用户的角色拥有的所有接口
ApiList = [
str(item.get('permission__api').replace('{id}', '([a-zA-Z0-9-]+)')) + ":" + str(
item.get('permission__method')) + '$' for item in userApiList if item.get('permission__api')]
new_api_ist = api_white_list + ApiList
new_api = api + ":" + str(method)
# print(api, new_api, method, new_api_ist)
for item in new_api_ist:
matchObj = re.match(item, new_api, re.M | re.I)
if matchObj is None:
continue
else:
return True
else:
return False
使用时可以在视图的 permission_classes = [CustomPermission] 加入到列表中


Django rest_framework用户认证和权限的更多相关文章

  1. python 全栈开发,Day79(Django的用户认证组件,分页器)

    一.Django的用户认证组件 用户认证 auth模块 在进行用户登陆验证的时候,如果是自己写代码,就必须要先查询数据库,看用户输入的用户名是否存在于数据库中: 如果用户存在于数据库中,然后再验证用户 ...

  2. COOKIE与SESSION、Django的用户认证、From表单

    一.COOKIE 与 SESSION 1.简介 1.cookie不属于http协议范围,由于http协议无法保持状态,但实际情况,我们却又需要“保持状态”,因此cookie就是在这样一个场景下诞生. ...

  3. Django--分页器(paginator)、Django的用户认证、Django的FORM表单

    分页器(paginator) >>> from django.core.paginator import Paginator >>> objects = ['joh ...

  4. Django Rest Framework(认证、权限、限制访问频率)

    阅读原文Django Rest Framework(认证.权限.限制访问频率) django_rest_framework doc django_redis cache doc

  5. 深入一下Django的用户认证和cache

    深入一下Django的用户认证和cache 用户认证 首先明白一个概念,http协议是无状态的,也就是每一次交互都是独立的,那如何让服务器和客户端进行有状态的交互呢,现在较为常见的方法就是让客户端在发 ...

  6. 【django之用户认证】

    一.auth模块 模块导入 from django.contrib import auth 主要方法如下: 1 .authenticate()    提供了用户认证,即验证用户名以及密码是否正确,一般 ...

  7. Django组件-用户认证

    用户认证 一.auth模块 from django.contrib import auth django.contrib.auth中提供了许多方法,这里主要介绍其中的三个: 1.1 .authenti ...

  8. Django之用户认证组件

    auth模块 之前我们在进行用户登录验证的时候,都是自己写代码,接收用户提交的数据,然后去数据库取数据进行匹配验证,其实Django已经给我们提供了内置的用户认证功能.不信的话你可以打开models. ...

  9. Django框架----用户认证auth模块

    一.auth模块 auth模块:针对auth_user表 创建超级管理用户命令: Python manage.py createsuperuser添加用户名添加密码(至少8位)确认密码添加邮箱(可为空 ...

  10. Django之用户认证功能

    前言 做web应用对登录做用户身份认证,然后设置session是必不可少的,因为我们就需要把有权限访问本站视图的用户,单独建一张表记录到数据库里: Django作为一个大而全的框架,已经为我们做好了这 ...

随机推荐

  1. Java实现两字符串相似度算法

    1.编辑距离 编辑距离:是衡量两个字符串之间差异的度量,它表示将一个字符串转换为另一个字符串所需的最少编辑操作次数(插入.删除.替换). 2.相似度 计算方法可以有多种,其中一种常见的方法是将编辑距离 ...

  2. git中的ole mode 和 new mode提示问题

    git status 显示如下(文件内容其实并没有改变): old mode 100644 new mode 100755 原因是: 使用chmod修改过文件权限后,filemode会有变化. 解决办 ...

  3. linux开发基于iMX6ULL-uboot编译环境配置

    1.下载半导体官方的uboot和linux内核固件 2.下载uboot 3.下载linux内核(选择5.4版本的分支下载) 下载后如下所示 解压后如下 查看文件夹中的内容 创建一个git仓库然后开始自 ...

  4. 视觉BEV基本原理和方案解析

    BEV(Bird's-Eye-View)是一种鸟瞰视图的传感器数据表示方法,它的相关技术在自动驾驶领域已经成了"标配",纷纷在新能源汽车.芯片设计等行业相继量产落地.BEV同样在高 ...

  5. Vite4+Typescript+Vue3+Pinia 从零搭建(4) - 代码规范

    项目代码同步至码云 weiz-vue3-template 要求代码规范,主要是为了提高多人协同和代码维护效率,结合到此项目,具体工作就是为项目配置 eslint 和 prettier. editorc ...

  6. 金蝶云星空与吉客云电商ERP数据对接

    01 系统说明: 吉客云 吉客云: 从业务数字化和组织数字化两个方向出发,以生成流程的闭环为依归,致力于为企业的数字化升级提供落地工具.销售订单层面,吉客云对接了国内外主流的销售平台,兼容了电商渠道. ...

  7. top命令和ps命令

    top 命令和 ps 命令 ps 命令 ps 命令查看系统的瞬时信息.通常使用ps -ef | grep 进程名, -e 代表显示所有进程,-f 表示做一个更为完整的输出.经常使用这个命令获得进程的 ...

  8. 数据分析师如何做好PPT

    作为一名数据分析师,制作出色的PPT是非常重要的技能之一.一个好的PPT可以让你的数据洞察更加生动有趣,并有效传达给观众.以下是一些详细的步骤和技巧,帮助你成为一名擅长制作PPT的数据分析师: 确定目 ...

  9. 我最喜欢的白版应用,AI加持的新功能开源!强烈推荐

    Excalidraw 把他们的文本到图表的功能开源了 Excalidraw是一个虚拟白板应用,专门用于绘制类似手绘的图表.它提供了一个无限的.基于画布的白板,具有手绘风格,支持多种功能. 之前我分享的 ...

  10. [CF1416F] Showing Off

    题目链接 如果把方向看做有向边,整个图是一个内向基环树. 所以考虑哪些点有可能放在基环树的非环部分上,当且仅当一个点周围有严格小于他的点. 由于图一定是二分图(黑白染色),没有奇环,所有偶环一定可以拆 ...