Python 核心:Django 鉴权方案全解析
Django 作为 Python 最成熟的 Web 框架,其鉴权系统(Authentication & Authorization)是核心模块之一。它提供了开箱即用的用户认证、权限控制和会话管理,同时高度可扩展。Django 的鉴权方案基于 django.contrib.auth 模块,遵循“电池内置”原则,但允许自定义扩展。本文从基础到高级,深入解析 Django 4.x+(2026 最新版)的鉴权方案,包括原理、实现、对比和最佳实践。
1. Django 鉴权系统概述
核心概念:
- 认证(Authentication):验证用户身份(谁是你?),如用户名/密码、Token。
- 授权(Authorization):检查用户权限(你能做什么?),如访问特定视图、操作数据。
- 用户模型(User Model):默认
auth.User,可自定义扩展。 - 会话管理:基于 Session 或 Token 维护状态。
工作原理:
- 用户请求到达视图。
- 中间件(如
AuthenticationMiddleware)从请求中提取凭证(Cookie、Header),加载用户对象到request.user。 - 视图中使用装饰器(如
@login_required)检查认证/权限。 - 如果未认证,重定向到登录页或返回 401/403。
默认配置(settings.py):
INSTALLED_APPS = [
'django.contrib.auth', # 必须启用
'django.contrib.contenttypes', # 权限依赖
]
AUTH_USER_MODEL = 'auth.User' # 默认用户模型,可自定义如 'myapp.CustomUser'
MIDDLEWARE = [
'django.contrib.sessions.middleware.SessionMiddleware', # 会话支持
'django.contrib.auth.middleware.AuthenticationMiddleware', # 认证中间件
]
AUTHENTICATION_BACKENDS = ['django.contrib.auth.backends.ModelBackend'] # 默认后端
2. 内置认证方案详解
Django 提供了多种开箱即用的鉴权方案,按复杂度分类。
2.1 基于 Session 的用户名/密码认证(默认方案)
- 原理:用户登录后,Django 生成 Session ID 存入 Cookie,服务器端存储用户状态。
- 流程:
- 用户提交用户名/密码。
- 调用
authenticate(username, password)验证。 - 如果成功,调用
login(request, user)设置 Session。 - 后续请求携带 Cookie,中间件加载
request.user。
- 代码示例(views.py):
from django.contrib.auth import authenticate, login, logout
from django.http import JsonResponse
def login_view(request):
if request.method == 'POST':
username = request.POST['username']
password = request.POST['password']
user = authenticate(request, username=username, password=password)
if user is not None:
login(request, user)
return JsonResponse({'message': '登录成功'})
else:
return JsonResponse({'error': '凭证无效'}, status=401)
return JsonResponse({'error': '无效请求'}, status=400)
def logout_view(request):
logout(request)
return JsonResponse({'message': '登出成功'})
- 装饰器使用:
from django.contrib.auth.decorators import login_required
@login_required # 未登录重定向到登录页
def protected_view(request):
return JsonResponse({'user': request.user.username})
- 优点:简单、安全(服务器端存储)。
- 缺点:不适合分布式系统(需共享 Session),移动端不友好。
2.2 基于 Token 的认证(RESTful API 常用)
- 原理:登录后生成 Token,返回给客户端。后续请求在 Header 中携带 Token(如 Authorization: Token xxx)。
- 内置支持:Django REST Framework (DRF) 扩展了 Token 认证。
- 安装 DRF:
pip install djangorestframework - 配置(settings.py):
INSTALLED_APPS = ['rest_framework', 'rest_framework.authtoken']
REST_FRAMEWORK = {
'DEFAULT_AUTHENTICATION_CLASSES': [
'rest_framework.authentication.TokenAuthentication',
'rest_framework.authentication.SessionAuthentication',
],
}
- 代码示例(views.py):
from rest_framework.authtoken.models import Token
from rest_framework.decorators import api_view, authentication_classes, permission_classes
from rest_framework.permissions import IsAuthenticated
from rest_framework.response import Response
@api_view(['POST'])
def api_login(request):
# ... 验证用户名/密码 ...
token, created = Token.objects.get_or_create(user=user)
return Response({'token': token.key})
@api_view(['GET'])
@authentication_classes([TokenAuthentication])
@permission_classes([IsAuthenticated])
def api_protected(request):
return Response({'user': request.user.username})
- 客户端使用:Header 中
Authorization: Token <key> - 优点:无状态、适合 API、分布式系统。
- 缺点:Token 泄露风险大(需加密传输),无内置过期机制(需自定义)。
2.3 基于 JWT 的认证(高级 Token 方案)
- 原理:JSON Web Token(JWT)是自包含的 Token,包含用户数据、签名和过期时间。无需服务器存储。
- 第三方库:推荐
djangorestframework-simplejwt(pip install) - 配置(settings.py):
REST_FRAMEWORK = {
'DEFAULT_AUTHENTICATION_CLASSES': [
'rest_framework_simplejwt.authentication.JWTAuthentication',
],
}
SIMPLE_JWT = {
'ACCESS_TOKEN_LIFETIME': timedelta(minutes=5), # 访问 Token 有效期
'REFRESH_TOKEN_LIFETIME': timedelta(days=1), # 刷新 Token 有效期
}
- 代码示例:
from rest_framework_simplejwt.tokens import RefreshToken
@api_view(['POST'])
def jwt_login(request):
# ... 验证用户名/密码 ...
refresh = RefreshToken.for_user(user)
return Response({
'refresh': str(refresh),
'access': str(refresh.access_token),
})
# 使用:Header 中 Authorization: Bearer <access_token>
- 优点:无状态、可扩展、支持过期/刷新机制。
- 缺点:Token 较长、无法主动失效(需黑名单)。
3. 权限控制(Authorization)
Django 的权限系统基于用户、组和权限模型。
- 内置权限:CRUD 操作(如 ‘app.add_model’)。
- 检查方式:
- 装饰器:
@permission_required('app.change_model') - 代码中:
user.has_perm('app.add_model') - 组:用户可加入组,继承组权限。
- 自定义权限(models.py):
class Meta:
permissions = [
("can_publish", "Can publish posts"),
]
4. 自定义认证后端
默认后端是用户名/密码,可扩展支持邮箱、第三方登录等。
- 自定义后端(backends.py):
from django.contrib.auth.backends import ModelBackend
from django.contrib.auth import get_user_model
class EmailBackend(ModelBackend):
def authenticate(self, request, username=None, password=None, **kwargs):
UserModel = get_user_model()
try:
user = UserModel.objects.get(email=username)
if user.check_password(password):
return user
except UserModel.DoesNotExist:
return None
- 配置:
AUTHENTICATION_BACKENDS = ['path.to.EmailBackend']
5. 鉴权方案对比表
| 方案 | 状态性 | 适用场景 | 安全性 | 复杂度 | 扩展性 |
|---|---|---|---|---|---|
| Session | 有状态 | Web 应用、浏览器端 | 高 | 低 | 中 |
| Token (DRF) | 无状态 | REST API、移动端 | 中 | 中 | 高 |
| JWT | 无状态 | 微服务、分布式系统 | 高 | 高 | 高 |
| OAuth2 | 无状态 | 第三方登录(如 Google) | 高 | 高 | 高 |
6. 最佳实践与注意事项
- 自定义用户模型:项目启动时就定义
AbstractUser子类,避免迁移问题。 - 密码存储:始终用
make_password和check_password,默认 PBKDF2 算法。 - 安全配置:启用 CSRF、HTTPS,设置
SECURE_COOKIE。 - 性能优化:JWT 避免存敏感数据;Session 用 Redis 缓存。
- 第三方集成:用
django-allauth或django-oauth-toolkit支持社交登录/OAuth。 - 常见坑:未启用中间件导致
request.user为 AnonymousUser;自定义模型未设置USERNAME_FIELD。
Django 的鉴权系统强大且灵活,结合 DRF 可轻松构建企业级应用。掌握这些,你就能在 Python Web 开发中游刃有余!
如果想看完整项目代码、OAuth 示例或特定版本差异,随时告诉我!🚀