Django 如何实现自定义权限控制
首先,需要安装相应的依赖包。在命令行中执行以下命令:
pip install django pip install djangorestframework pip install djangorestframework-simplejwt
然后,在 Django 的 settings.py 文件中添加以下配置:
REST_FRAMEWORK = { 'DEFAULT_AUTHENTICATION_CLASSES': ( 'rest_framework_simplejwt.authentication.JWTAuthentication', ), } SIMPLE_JWT = { 'ACCESS_TOKEN_LIFETIME': timedelta(hours=1), 'REFRESH_TOKEN_LIFETIME': timedelta(days=1), }
这里设置了 REST Framework 使用 JWTAuthentication 进行身份验证,以及 simpleJWT 的配置。
接下来,定义一个 Views,用于返回 JWT Token。我们将使用 Django 中的默认 User 模型和认证系统。在 views.py 文件中添加以下内容:
from rest_framework.views import APIView from rest_framework.response import Response from rest_framework_simplejwt.tokens import RefreshToken from django.contrib.auth import authenticate # 获取 Token API class TokenObtainView(APIView): def post(self, request, *args, **kwargs): # 获取用户名和密码 username = request.data.get('username') password = request.data.get('password') # 验证用户名和密码 user = authenticate(request, username=username, password=password) if user is None: return Response({'error': '用户名或密码错误'}) # 生成 JWT Token refresh = RefreshToken.for_user(user) return Response({ 'refresh': str(refresh), 'access': str(refresh.access_token), })
此处定义了一个 APIView,用于返回 JWT Token。首先从请求数据中获取用户名和密码,然后使用 authenticate() 方法验证用户。如果认证成功,就生成并返回 JWT Token。
最后,在 urls.py 文件中添加以下 URL 映射:
from django.urls import path from .views import TokenObtainView urlpatterns = [ path('api/token/', TokenObtainView.as_view(), name='token_obtain'), ]
这样,请求 /api/token/ 就会返回一个包含 Token 的 JSON 响应。
以上就是一个简单的 Django + simpleJWT 的集成示例。当然,在实际应用中,还需要对 views.py 文件进行更详细的编写,例如创建用户、获取用户信息等。
在 JWT Token 过期的情况下,客户端需要使用 Refresh Token 来刷新 Token。
通常情况下,客户端在登录成功后会收到两个 Token:Access Token 和 Refresh Token。Access Token 是用于身份验证的 Token,而 Refresh Token 则用于刷新 Access Token。
当 Access Token 过期时,客户端需要使用 Refresh Token 来向服务器请求一个新的 Access Token。在 simpleJWT 中,可以使用 Refresh Token 来刷新 Access Token。Refresh Token 的默认到期时间是 30 天,可以在配置中进行设置。
以下是使用 simpleJWT 刷新 Token 的一个示例:
from rest_framework_simplejwt.tokens import RefreshToken # 获取 Token 刷新 API class TokenRefreshView(APIView): def post(self, request, *args, **kwargs): # 获取 Refresh Token refresh = request.data.get('refresh') # 刷新 Access Token try: token = RefreshToken(refresh) return Response({ 'access': str(token.access_token), }) except TokenError as e: return Response({'error': str(e)})
在上述代码中,我们定义了一个 APIView 来刷新 Access Token。在请求数据中,我们获取了 Refresh Token,然后使用它来刷新 Access Token。
通过以上代码示例,我们可以了解到如何使用 simpleJWT 来刷新 Token。关键点是在 simpleJWT 中,我们可以使用 Refresh Token 来刷新 Access Token。在需要刷新 Token 的时候,客户端需要向服务器发送 Refresh Token,然后服务器就会使用它来生成新的 Access Token,并将其返回给客户端。
在 Django 中,可以使用自定义权限控制对 API 进行访问控制。在 simpleJWT 中,我们可以使用自定义 permissions 类来对 Access Token 进行鉴权。
以下是简单示例:
from rest_framework import permissions class IsAdminUser(permissions.BasePermission): """ 只允许管理员访问 """ def has_permission(self, request, view): return request.user and request.user.is_superuser class MyAPIView(APIView): permission_classes = [IsAdminUser] def get(self, request, *args, **kwargs): return Response({'message': '只有管理员可以访问'})
在上述代码中,我们首先定义了一个自定义权限类 IsAdminUser,继承自 permissions.BasePermission。在该类中,我们重写了 has_permission 方法,来验证 Access Token 中的用户是否是管理员。只有当用户是管理员时,该方法返回True,否则返回False。
在 MyAPIView 中,我们将权限类设置为 IsAdminUser。这样,当用户访问该 API 时,Django Rest Framework 会在执行视图方法之前先执行 IsAdminUser 的 has_permission 方法。只有当该方法返回 True 时,才会允许通过访问控制。
通过上述示例,我们可以实现自定义权限控制,来对 Access Token 进行鉴权。自定义权限控制是非常灵活的,可以根据不同的场景定义不同的权限类,从而实现精细化的访问控制。
如果您希望实现的是基于多个自定义权限组的权限检查,可以创建多个自权限,然后将这些权限类添加到 Django 视图的 permission_classes
属性。以下是一个示例:
首先,创建多个权限类。在这个例子中,我们假设有两个权限组:GroupA
和 GroupB
,并根据用户的所属组确定他们的访问权限。
from rest_framework import permissions class GroupAPermission(permissions.BasePermission): """ 允许 GroupA 的用户访问 """ def has_permission(self, request, view): return request.user and request.user.groups.filter(name='GroupA').exists() class GroupBPermission(permissions.BasePermission): """ 允许 GroupB 的用户访问 """ def has_permission(self, request, view): return request.user and request.user.groups.filter(name='GroupB').exists()
然后,在视图中将这些权限类作为 permission_classes
的元素添加:
from rest_framework.views import APIView from rest_framework.response import Response class MyAPIView(APIView): permission_classes = [GroupAPermission, GroupBPermission] def get(self, request, *args, **kwargs): return Response({'message': 'GroupA 或者 GroupB 的用户可以访问此 API'})
在这个例子中,当用户访问 MyAPIView 时,Django Rest Framework 将会检查这个用户是否具有 GroupAPermission
或者 GroupBPermission
。如果满足其中任意一个权限类的条件,那么用户将可以访问该 API。 用户需要至少属于 GroupA 或 GroupB 之一才可以访问该视图。
请注意,我们在这里给 permission_classes 提供了一个权限类列表。API 视图将根据列表中的任意一个权限类进行鉴权。你可以修改权限列表来为不同的视图控制不同的访问权限。
在这种情况下,您可以创建一个自定义权限类,并检查用户所属的任何组是否具有相应的权限。例如,您可以在 Django 后台为每个组定义一个具有读取权限(view
权限)的权限对象。然后,在自定义权限类中检查用户组是否具有此权限。
首先,在 models.py
文件中创建一个新的权限。例如,创建一个名为 APICanRead
的权限。为了更方便控制权限,我们可以将其附加到一个模型,例如一个名为 PermissionControl
的空模型:
from django.db import models class PermissionControl(models.Model): class Meta: permissions = [ ("APICanRead", "Can view API"), ] default_permissions = [] # 清空默认权限,以免混淆
接下来,在自定义权限类中检查用户所属的任何组是否具有这个权限:
from rest_framework import permissions class ApiReadPermission(permissions.BasePermission): """ 只允许具有读取权限的用户组访问。 """ def has_permission(self, request, view): # 检查用户所属的所有组是否具有"APICanRead"权限。 return ( request.user and request.user.groups.filter(permissions__codename="APICanRead").exists() )
现在,将 ApiReadPermission
类添加到您的 APIView:
from rest_framework.views import APIView from rest_framework.response import Response class MyAPIView(APIView): permission_classes = [ApiReadPermission] def get(self, request, *args, **kwargs): return Response({'message': '可以访问此 API 的用户组具有读权限'})
在这个示例中,我们首先创建了一个名为 APICanRead
的新权限,并将其附加到一个名为 PermissionControl
的模型。然后,我们在自定义权限类 ApiReadPermission
中检查用户所属的任何组是否具有此权限。最后,我们将此权限类添加到APIView。
现在,您可以在 Django 后台为不同的用户组分配或删除 APICanRead
权限。只有具有此权限的用户组才能访问该 API。如果您需要添加新的组(如 GroupC、GroupD),只需在后台为新组分配 APICanRead
权限即可。这种方式使得权限管理变得更加灵活和可扩展。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 开发者必知的日志记录最佳实践
· SQL Server 2025 AI相关能力初探
· Linux系列:如何用 C#调用 C方法造成内存泄露
· AI与.NET技术实操系列(二):开始使用ML.NET
· 记一次.NET内存居高不下排查解决与启示
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· 开源Multi-agent AI智能体框架aevatar.ai,欢迎大家贡献代码
· Manus重磅发布:全球首款通用AI代理技术深度解析与实战指南
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· AI技术革命,工作效率10个最佳AI工具