最好是将用户权限验证和Token验证放在Django中间件中,以便对所有视图函数进行校验。
下面是一段示例代码,演示了如何实现中间件来进行用户权限验证和Token验证
middleware.py
| from django.contrib.auth import authenticate |
| from django.http import HttpResponseForbidden |
| from rest_framework.authtoken.models import Token |
| |
| class AuthMiddleware: |
| def __init__(self, get_response): |
| self.get_response = get_response |
| |
| def __call__(self, request): |
| user = authenticate(request=request) |
| |
| if user and user.is_active: |
| request.user = user |
| return self.get_response(request) |
| else: |
| return HttpResponseForbidden() |
| |
| class TokenAuthMiddleware: |
| def __init__(self, get_response): |
| self.get_response = get_response |
| |
| def __call__(self, request): |
| if 'HTTP_AUTHORIZATION' in request.META: |
| auth_header = request.META['HTTP_AUTHORIZATION'] |
| auth_token = auth_header.split(' ')[1] |
| try: |
| token = Token.objects.get(key=auth_token) |
| request.user = token.user |
| except Token.DoesNotExist: |
| pass |
| |
| return self.get_response(request) |
该示例代码包括以下部分:
- 实现了AuthMiddleware中间件类,用于用户权限验证。在__call__方法中,使用authenticate函数来验证用户,如果验证成功,将用户信息存储在请求对象中,否则返回HttpResponseForbidden。
- 实现了TokenAuthMiddleware中间件类,用于Token验证。在__call__方法中,首先检查请求头中是否有Authorization字段,如果有,则获取Token值,并使用Token.objects.get函数查询数据库中是否有匹配的Token。如果找到了Token,则将该Token对应的用户信息存储在请求对象中。
- 将这两个中间件添加到Django项目的中间件列表中,以便对所有视图函数进行用户权限验证和Token验证。例如,在settings.py文件中添加以下代码:
| MIDDLEWARE = [ |
| |
| 'path.to.AuthMiddleware', |
| 'path.to.TokenAuthMiddleware', |
| |
| ] |
| |
对于Token的存储方式,有以下几种常见的选择:
- 数据库存储:将Token保存在数据库中,每次需要验证Token时,从数据库中查询Token并进行验证。这种方式的优点是安全性高,不容易被攻击,而且Token的管理也比较方便。缺点是每次需要验证Token时都要查询数据库,会增加一定的性能开销。
- 前端缓存存储:将Token保存在前端缓存中,每次需要验证Token时,直接从前端缓存中读取。这种方式的优点是速度快,不需要每次都查询数据库,而且可以降低服务器的压力。缺点是安全性相对较低,容易被攻击。
- 分布式缓存存储:将Token保存在分布式缓存中,每次需要验证Token时,直接从缓存中读取。这种方式结合了前两种方式的优点,安全性较高,速度也比较快,而且可以支持分布式部署。
推荐使用第三种方法
分布式缓存存储可以使用诸如Redis、Memcached等分布式缓存系统来实现
下面以Redis为例,介绍如何实现基于Redis的Token存储
首先需要在Django的settings.py中配置Redis:
| CACHES = { |
| "default": { |
| "BACKEND": "django_redis.cache.RedisCache", |
| "LOCATION": "redis://127.0.0.1:6379/1", |
| "OPTIONS": { |
| "CLIENT_CLASS": "django_redis.client.DefaultClient", |
| } |
| } |
| } |
| |
| SESSION_ENGINE = "django.contrib.sessions.backends.cache" |
| SESSION_CACHE_ALIAS = "default" |
| |
其中,LOCATION为Redis的连接地址,可以根据实际情况进行配置
然后可以使用Django的缓存API来实现Token的存储和读取。例如:
| from django.core.cache import cache |
| |
| # 存储Token |
| # 可以使用cache.set()方法中的timeout参数来设置过期时间 |
| cache.set("token_key", "token_value",timeout=600) |
| |
| # 读取Token |
| token_value = cache.get("token_key") |
| |
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 震惊!C++程序真的从main开始吗?99%的程序员都答错了
· winform 绘制太阳,地球,月球 运作规律
· 【硬核科普】Trae如何「偷看」你的代码?零基础破解AI编程运行原理
· 上周热点回顾(3.3-3.9)
· 超详细:普通电脑也行Windows部署deepseek R1训练数据并当服务器共享给他人