当前位置: 首页 > news >正文

Django一分钟:DRF快速实现JWT认证与RBAC权限校验

一、项目创建并实现JWT认证

1. 下载依赖

下载djangodjangorestframeworkdjangorestframework_simplejwt

pip install django djangorestframework djangorestframework_simplejwt

2. 创建项目

  • 启动Django项目
django-admin startproject <myproject>
cd myproject

用你实际的项目名称替换<myproject>

  • 创建app
python manage.py startapp <myapp>

用你实际的app名称替换<myapp>

  • 当前项目目录如下
myproject/
├── myproject/
|   ├── __init__.py
|   ├── settings.py
|   ├── urls.py
|   ├── wsgi.py
|   └── asgi.py
├── myapp/
│   ├── __init__.py
│   ├── admin.py
│   ├── apps.py
│   ├── migrations/
│   │   └── __init__.py
│   ├── models.py
│   ├── tests.py
│   ├── urls.py
│   └── views.py
└── manage.py
  • 在配置文件中设置app

settings.py文件中配置好需要的app

INSTALLED_APPS = [...'rest_framework','rest_framework_simplejwt','myapp',
]

3. 配置JWT

# settings.py
from datetime import timedelta # 添加在INSTALLED_APPS下
# 该配置用于指定默认使用的权限类和授权类
REST_FRAMEWORK = {'DEFAULT_PERMISSION_CLASSES': ('rest_framework.permissions.IsAuthenticated',),'DEFAULT_AUTHENTICATION_CLASSES': ('rest_framework_simplejwt.authentication.JWTAuthentication',),
}# 用于配置令牌过期时间等参数
SIMPLE_JWT = {'ACCESS_TOKEN_LIFETIME': timedelta(minutes=60),'SLIDING_TOKEN_REFRESH_LIFETIME': timedelta(days=1),'SLIDING_TOKEN_LIFETIME': timedelta(days=30),'SLIDING_TOKEN_REFRESH_LIFETIME_LATE_USER': timedelta(days=1),'SLIDING_TOKEN_LIFETIME_LATE_USER': timedelta(days=30),
}

4. 配置路由

from rest_framework_simplejwt.views import TokenObtainPairView, TokenRefreshView
from django.contrib import admin
from django.urls import path, includeurlpatterns = [path('admin/', admin.site.urls),path('api/token/', TokenObtainPairView.as_view(), name='token_obtain_pair'),path('api/token/refresh/', TokenRefreshView.as_view(), name='token_refresh'),    path('', include('myapp.urls')), 
]

5. 创建视图类并配置授权

创建视图类,并为视图类添加权限要求,这里我们先添加基本的授权要求,即要求用户必须在请求头中携带我们的JWT token才能访问相应的路径。

from rest_framework.response import Response
from rest_framework.views import APIView
from rest_framework.permissions import IsAuthenticated
from rest_framework_simplejwt.authentication import JWTAuthenticationclass BlogView(APIView):permission_classes = (IsAuthenticated,)authentication_classes = (JWTAuthentication,)def get(self, request, *args, **kwargs):return Response({'msg': 'success', 'detail': 'myblog'})

未新创建的视图创建urls.py文件

touch myapp/urls.py

创建完成后添加配置

from django.urls import path
from myapp.views import BlogViewurlpatterns = [path('blog/', BlogView.as_view(), name='blog'),
]

6. 启动项目

数据库迁移

python manage.py migrate

启动项目

python manage.py createsuperuser
python manage.py runserver

二、测试JWT

在上一节的最后我们创建了一个管理员账户,假如为:

username: admin
password: admin123

请求授权接口的方法:

  • 使用djangorestframework_simplejwt创建的token接口,请求token时要求我们使用POST方法,并在请求体中携带用户名和密码:{"username": "admin", "password": "admin123"}
  • 如果请求成功,该接口会返回两个token,一个是access_token,另一个是refresh_token。当请求需要授权权限的接口时,需要在请求头中携带access_token
  • access_token的存活时间较短,refresh token的存活时间长,access_token过期需要获取新令牌,获取新令牌需要携带在请求头中携带refresh_token../refresh/token端口进行请求。
  • 所谓携带token指的是在请求头中添加Authorization字段,具体的格式时Authorization: Bearer <token>,在代码中体现为{"Authorization": f"Bearer {token}"}

现在我们需要一个客户端来测试我们创建的后端服务,你可以通过postman创建测试请求,也可以通过http标准库、requestsaiohttp创建客户端进行测试,下面以aiohttp为例:

import asyncio
from aiohttp import ClientSessionclass Client:"""测试客户端"""def __init__(self):self.url = "http://localhost:8000/"self.user = {"username": "admin", "password": "admin123"}self.session = ClientSession()self.access_token = ""self.refresh_token = ""async def close(self):await self.session.close()async def get_token(self):"""获取token"""url = self.url + "auth/token/"async with self.session.post(url, json=self.user) as response:if response.status == 200:data = await response.json()if "access" in data and "refresh" in data:self.access_token = data["access"]self.refresh_token = data["refresh"]print(f"access_token: {self.access_token}")print(f"refresh_token: {self.refresh_token}")else:data.update({"error": "fail to get token"})print(data)else:print(f"Error status code: {response.status}")async def refresh_token(self):"""刷新token"""url = self.url + "auth/token/refresh/"headers = {"Authorization": f"Bearer {self.refresh_token}"}async with self.session.post(url, headers=headers) as response:if response.status == 200:data = await response.json()if "access" in data:self.access_token = data["access"]print(f"access_token: {self.access_token}")else:data.update({"error": "fail to refresh token"})print(data)else:print(f"Error status code: {response.status}")async def get_blog(self):"""获取博客"""url = self.url + "blog/"headers = {"Authorization": f"Bearer {self.access_token}"}async with self.session.get(url, headers=headers) as response:if response.status == 200:print(await response.json())else:print(f"Error status code: {response.status}")async def main():client = Client()await client.get_token()await client.get_blog()await client.close()if __name__ == "__main__":asyncio.run(main())

在前端项目中对接该接口,需要使用axiosfetch发起请求,可以把获取到的token存贮在localStorage中,每次请求时携带授权请求头。

三、权限分配与验证

1. Django Auth基础知识

在本文中我们将使用Django自带的auth系统来实现RBAC权限校验,在此之前需要了解一些关于Djangoauth系统的基础知识。

注册Django的auth应用,在初次进行migrate数据库迁移的时候,Django会自动在数据库中创建5张表:用户、权限、组以及三者两两之间的关系表。这在RBAC权限管理系统的数据库表设计中非常常见。

  • user
  • group
  • permission
  • user_group
  • group_permission
  • user_permission

在使用Django的认证系统我们需要知道以下几件事:

  1. 我们可以自己在permission表中创建一些权限,但通常来说不需要,Django在执行数据库迁移时,会自动为已注册app的模型创建增、删、改、查四个权限。
  2. 我们可以为用户分配权限,本质上就是在user_permission关系表中创建一条数据。我们也可以创建一个组,你可以将组命名为“采购部门”,为组分配权限,被分配到这个组中的用户将自动获取这个组的权限。
  3. 通过createsuperuser 创建的超级用户会拥有所有的权限(准确来说是自动通过权限认证),普通用户的权限需要自己分配。

2, 为用户分配权限

打开Django的shell控制台:

python manage.py shell

创建测试用户:

from django.contrib.auth.models import User
User.objects.create_user(username="test", email="test@qq.com",password="test123")

为新创建的用户分配权限view_blog

from django.contrib.auth.models import Permission
permission = Permission.objects.get(codename="view_blog")
user = User.objects.get(username="test")
user.user_permissions.add(permission)
user.save()

此时你可以通过一些数据库工具查询到,你的sqlite数据库中的user_permission关系表中新增了一条数据,这就表示我们为test用户分配了view_blog权限。

3. 为路视图类添加权限

我们可以通过drf自定义权限类的方式为APIView整体添加权限限制:

from rest_framework.response import Response
from rest_framework.views import APIView
from rest_framework.permissions import IsAuthenticated
from rest_framework_simplejwt.authentication import JWTAuthentication
from apps.authorization.decorators import class_permission_required
from rest_framework.permissions import BasePermissionclass ViewBlogP(BasePermission):def has_permission(self, request, view):return request.user.has_perm('auth.view_user')class BlogView(APIView):permission_classes = (IsAuthenticated, ViewBlogP)authentication_classes = (JWTAuthentication,)def get(self, request, *args, **kwargs):return Response({'msg': 'success', 'detail': 'myblog'})

4.为视图类方法添加权限

django的permission_required装饰器可以为视图方法创建权限要求,不过permission_required不能直接在视图类的方法上直接使用,我们需要创建一个适配装饰器如下,你可以放置在utils.py文件中:

# utils.py
from django.contrib.auth.decorators import permission_required
import functoolsdef class_permission_required(perm, login_url=None, raise_exception=False):"""适配装饰器使得permission_required装饰器在视图类的成员方法上也能使用"""original_decorator = permission_required(perm, login_url, raise_exception)def adapter(view_method):@functools.wraps(view_method)def wrapped_view(self, request, *args, **kwargs):def new_func(request, *args, **kwargs):return view_method(self, request, *args, **kwargs)decorated_func = original_decorator(new_func)return decorated_func(request, *args, **kwargs)return wrapped_viewreturn adapter

使用方法:

class BlogView(APIView):permission_classes = (IsAuthenticated,)authentication_classes = (JWTAuthentication,)@class_permission_required('auth.view_user', raise_exception=True)def get(self, request, *args, **kwargs):return Response({'msg': 'success'})

关于此方法的更多细节请参考我的另一篇文章,欢迎订阅我的免费专栏Django一分钟。

相关文章:

Django一分钟:DRF快速实现JWT认证与RBAC权限校验

一、项目创建并实现JWT认证 1. 下载依赖 下载django、djangorestframework、djangorestframework_simplejwt pip install django djangorestframework djangorestframework_simplejwt2. 创建项目 启动Django项目 django-admin startproject <myproject> cd myprojec…...

面试题(六)

48、设计模式 49、继承是否会破坏封装&#xff1f; 继承在面向对象编程中是一个重要的概念&#xff0c;但它确实可能对封装产生影响&#xff0c;具体情况取决于如何使用继承。以下是对这个问题的分析&#xff1a; 封装的定义 封装是面向对象编程中的一个基本原则&#xff0…...

CSS 实现文本溢出省略号显示,含单行与多行文本溢出

&#x1f680; 个人简介&#xff1a;某大型国企资深软件研发工程师&#xff0c;信息系统项目管理师、CSDN优质创作者、阿里云专家博主&#xff0c;华为云云享专家&#xff0c;分享前端后端相关技术与工作常见问题~ &#x1f49f; 作 者&#xff1a;码喽的自我修养&#x1f9…...

Redis中String命令的基础操作

文章目录 Redis中String命令的基础操作一、引言二、String类型的基础命令1、设置与获取值1.1、SET命令1.2、GET命令 2、字符串操作2.1、APPEND命令2.2、GETRANGE命令2.3、SETRANGE命令2.4、STRLEN命令 3、数值操作3.1、INCR命令3.2、DECR命令3.3、INCRBY和DECRBY命令 三、应用场…...

策略模式+模版模式+工厂模式

工厂模式&#xff1a; &#xff08;1&#xff09;避免类中出现过多的组合依赖 &#xff08;2&#xff09;同时减少代码中出现过多的if...else if...语句 &#xff08;2&#xff09;将调用者跟我们的实现类解耦 模版模式&#xff1a; &#xff08;1&#xff09;功能复用 &…...

云计算平台层(PaaS)指的是什么?常见的应用场景盘点

云计算平台层(PaaS)指的是什么&#xff1f;云计算平台层&#xff08;PaaS&#xff09;&#xff0c;全称PlatformasaService&#xff08;平台即服务&#xff09;&#xff0c;是云计算服务的一种重要模式。为用户提供了一个基于云端的开发和部署环境&#xff0c;允许用户开发、运…...

搜索引擎简介

搜索引擎架构 整个搜索引擎分为三个系统 爬虫系统 索引系统 线上搜素服务 爬虫系统 爬虫分为两个阶段&#xff1a; 第一阶段&#xff1a;根据目标网站的列表页&#xff0c;爬对应的文档 URL 第二阶段&#xff1a;根据文档 URL&#xff0c;下载文档内容 触发器&#xff1…...

每天认识几个maven依赖(aislib+A1TRMI+Andromda+Annogen)

十七、aislib 1、是什么&#xff1f; aislib用于与人工智能&#xff08;AI&#xff09;相关的任务。这可能包括支持机器学习、数据分析或其他 AI 功能的工具。用于集成或扩展 AI 功能到 Java 项目中。 2、有什么用&#xff1f; 机器学习&#xff1a; 提供各种机器学习算法和…...

每日算法1(快慢指针)

通过一道题来了解快慢指针 这是一道力扣的算法题&#xff0c;首先来读题&#xff0c;是删除链表的中间元素&#xff0c;先来分析一下题&#xff0c;链表一共有三种可能&#xff0c;第一种是空链表&#xff0c;第二种链表的个数是偶数&#xff0c;第三种是链表的个数是奇数&…...

基于RealSense D435相机简单实现手部姿态重定向

基于Intel RealSense D435 相机和 MediaPipe的手部姿态检测&#xff0c;进一步简单实现手部姿态与机器人末端的重定向。 假设已经按照【基于 RealSenseD435i相机实现手部姿态检测】配置好所需的库和环境&#xff0c;并且有一个可以控制的机器人接口。 一、手部姿态重定向介绍 …...

Linux下搭建iSCSI共享存储-Tgt

Linux下搭建iSCSI共享存储-Tgt 在Linux上使用tgt搭建iSCSI共享存储&#xff0c;可以实现多个客户端同时访问共享存储。 1. 安装iSCSI Target软件包 使用下面命令安装&#xff1a; # centos sudo yum install scsi-target-utils sudo systemctl status tgtd# ubuntu sudo ap…...

js中正则表达式中【exec】用法深度解读

exec() 是 JavaScript 正则表达式对象&#xff08;RegExp&#xff09;中的一个方法&#xff0c;用于匹配字符串中的特定模式&#xff0c;并返回匹配结果。它比 test() 和 match() 更强大&#xff0c;因为它不仅仅返回匹配成功与否&#xff0c;还返回匹配的具体内容及其相关信息…...

Dockerfile的详解与案例

《Dockerfile 详解与案例》 一、Dockerfile 简介 Dockerfile 是一个用来构建 Docker 镜像的文本文件&#xff0c;它包含了一系列指令&#xff0c;用于描述如何创建一个 Docker 镜像。通过 Dockerfile&#xff0c;你可以定义镜像的基础环境、安装软件包、设置环境变量等操作&a…...

[spring]用MyBatis XML操作数据库 其他查询操作 数据库连接池 mysql企业开发规范

文章目录 一. MyBatis XML配置文件1. 配置链接字符串和MyBatis2. 写持久层代码方法定义Interface方法实现xml测试 3. 增删改查增:删改查 二. 开发规范(mysql)三. 其他查询操作1. 多表查询2. #{} 和 ${}(面试题)使用区别 排序功能like查询 三. 数据库连接池 一. MyBatis XML配置…...

[产品管理-33]:实验室技术与商业化产品的距离,实验室技术在商业化过程中要越过多少道“坎”?

目录 一、实验室技术 1.1 实验室研究性技术 1.2 技术发展的S曲线 技术发展S曲线的主要阶段和特点 技术发展S曲线的意义和应用 二、实验室技术商业化的路径 2.1 实验室技术与商业化产品的距离 1、技术成熟度与稳定性 - 技术自身 2、市场需求与适应性 - 技术是满足需求 …...

【有啥问啥】 Self-Play技术:强化学习中的自我进化之道

Self-Play技术&#xff1a;强化学习中的自我进化之道 在人工智能的快速发展中&#xff0c;强化学习&#xff08;Reinforcement Learning, RL&#xff09;已成为推动智能体自主学习与优化的关键力量。Self-Play技术&#xff0c;作为强化学习领域的一项前沿创新&#xff0c;通过…...

LCR 008. 长度最小的子数组

文章目录 1.题目2.思路3.代码 1.题目 LCR 008. 长度最小的子数组 给定一个含有 n 个正整数的数组和一个正整数 target 。 找出该数组中满足其和 ≥ target 的长度最小的 连续子数组 [numsl, numsl1, ..., numsr-1, numsr] &#xff0c;并返回其长度**。**如果不存在符合条件…...

uniApp 解决uniapp三方地图获取位置接口的请求次数限制问题,分别提供 Android 和 iOS 的实现方法(原生插件获取)

以下是使用 UniApp 编写获取位置信息的原生插件步骤&#xff0c;这里分别提供 Android 和 iOS 的实现方法。 一、Android 端实现 创建原生插件模块 在 UniApp 项目目录下创建一个目录&#xff0c;比如 nativeplugins/android/locationPlugin。使用 Android Studio 创建一个 An…...

Zabbix Agent 监控 MySQL 进程状态

1. 使用 Zabbix Agent 监控 MySQL 进程状态 这是最简单的方式,通过 Zabbix Agent 监控 MySQL 进程是否在运行。具体步骤如下: 步骤1: 确认 MySQL 进程的名称 在你的 CentOS 服务器上,运行以下命令来确认 MySQL 进程的名称: ps aux | grep mysql通常,MySQL 服务的进程名…...

【模型】感知器

感知器是最早的人工神经网络之一&#xff0c;也是现代深度学习的基础之一。 1. 感知器&#xff08;Perceptron&#xff09; 1.1 定义与功能 感知器是一种线性二分类模型&#xff0c;旨在模拟生物神经元的基本功能。它通过对输入特征进行加权求和&#xff0c;并应用激活函数来…...

5分钟掌握:如何在Blender中快速安装和使用VRM插件终极指南

5分钟掌握&#xff1a;如何在Blender中快速安装和使用VRM插件终极指南 【免费下载链接】VRM-Addon-for-Blender VRM Importer, Exporter and Utilities for Blender 2.93 to 5.1 项目地址: https://gitcode.com/gh_mirrors/vr/VRM-Addon-for-Blender 想在Blender中轻松处…...

探索Windows HEIC缩略图:跨平台照片管理深度解析

探索Windows HEIC缩略图&#xff1a;跨平台照片管理深度解析 【免费下载链接】windows-heic-thumbnails Enable Windows Explorer to display thumbnails for HEIC/HEIF files 项目地址: https://gitcode.com/gh_mirrors/wi/windows-heic-thumbnails Windows HEIC缩略图…...

LearningX:构建结构化开发者知识体系,从基础到架构的实践指南

1. 项目概述&#xff1a;一个面向开发者的系统性学习仓库最近在GitHub上看到一个挺有意思的项目&#xff0c;叫“LearningX”。光看名字&#xff0c;你可能会觉得这又是一个普通的“Awesome-XXX”列表&#xff0c;或者是一堆学习资料的简单堆砌。但当我点进去&#xff0c;花了一…...

Fast-GitHub:三步安装解决国内GitHub访问难题的终极指南

Fast-GitHub&#xff1a;三步安装解决国内GitHub访问难题的终极指南 【免费下载链接】Fast-GitHub 国内Github下载很慢&#xff0c;用上了这个插件后&#xff0c;下载速度嗖嗖嗖的~&#xff01; 项目地址: https://gitcode.com/gh_mirrors/fa/Fast-GitHub 你是否经常因为…...

进化算法驱动机械爪设计优化:从原理到EvoClaw项目实践

1. 项目概述与核心价值最近在GitHub上看到一个挺有意思的项目&#xff0c;叫“EvoClaw”。光看这个名字&#xff0c;可能有点摸不着头脑&#xff0c;但点进去一看&#xff0c;发现这是一个关于“进化算法驱动的机械爪设计优化”的开源项目。简单来说&#xff0c;就是利用计算机…...

告别ET1100?聊聊AX58100这颗高性价比EtherCAT从站芯片的升级体验

告别ET1100&#xff1f;AX58100高性价比EtherCAT从站芯片的工业升级实战 当工业设备制造商面临从传统控制架构向实时以太网迁移时&#xff0c;EtherCAT从站芯片的选型往往成为关键转折点。十年前&#xff0c;ET1100凭借其稳定的性能和相对友好的开发门槛&#xff0c;成为许多工…...

【C语言】printf格式化输出:你真的理解“四舍五入”的陷阱吗?

1. 从printf的"四舍五入"陷阱说起 那天我在调试一个财务计算程序时&#xff0c;发现金额显示总差那么几分钱。比如3.145元应该显示为3.15&#xff0c;但程序输出却是3.14。这让我想起刚学C语言时踩过的坑——printf的格式化输出并不像数学课教的四舍五入那样简单。 先…...

从零构建情感大语言模型:基于EmoLLM的实践指南

1. 项目概述&#xff1a;当大语言模型学会“察言观色”最近在折腾一个挺有意思的开源项目&#xff0c;叫SmartFlowAI/EmoLLM。光看名字你可能就猜到了&#xff0c;这玩意儿跟“情绪”和“大语言模型”有关。没错&#xff0c;它的核心目标就是让冷冰冰的LLM&#xff08;Large La…...

基于MCP协议构建AI金融数据可视化服务器:从原理到实战部署

1. 项目概述&#xff1a;一个为AI智能体提供实时金融数据可视化的MCP服务器最近在折腾AI智能体&#xff08;Agent&#xff09;的生态&#xff0c;发现一个挺有意思的痛点&#xff1a;当你想让AI帮你分析股票、基金或者加密货币时&#xff0c;它往往只能给你干巴巴的数字和文字描…...

初创团队如何通过Taotoken的Token Plan实现成本可控的AI应用开发

&#x1f680; 告别海外账号与网络限制&#xff01;稳定直连全球优质大模型&#xff0c;限时半价接入中。 &#x1f449; 点击领取海量免费额度 初创团队如何通过Taotoken的Token Plan实现成本可控的AI应用开发 对于预算敏感的初创团队和独立开发者而言&#xff0c;在开发AI应…...