Python核心:Django鉴权方案全解析

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 维护状态。

工作原理

  1. 用户请求到达视图。
  2. 中间件(如 AuthenticationMiddleware)从请求中提取凭证(Cookie、Header),加载用户对象到 request.user
  3. 视图中使用装饰器(如 @login_required)检查认证/权限。
  4. 如果未认证,重定向到登录页或返回 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,服务器端存储用户状态。
  • 流程
  1. 用户提交用户名/密码。
  2. 调用 authenticate(username, password) 验证。
  3. 如果成功,调用 login(request, user) 设置 Session。
  4. 后续请求携带 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 认证。
  • 安装 DRFpip 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_passwordcheck_password,默认 PBKDF2 算法。
  • 安全配置:启用 CSRF、HTTPS,设置 SECURE_COOKIE
  • 性能优化:JWT 避免存敏感数据;Session 用 Redis 缓存。
  • 第三方集成:用 django-allauthdjango-oauth-toolkit 支持社交登录/OAuth。
  • 常见坑:未启用中间件导致 request.user 为 AnonymousUser;自定义模型未设置 USERNAME_FIELD

Django 的鉴权系统强大且灵活,结合 DRF 可轻松构建企业级应用。掌握这些,你就能在 Python Web 开发中游刃有余!

如果想看完整项目代码、OAuth 示例或特定版本差异,随时告诉我!🚀

文章已创建 3707

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

相关文章

开始在上面输入您的搜索词,然后按回车进行搜索。按ESC取消。

返回顶部