R / Richie全部文章 ↑

Python · 2 分钟阅读

认证系统的应用

实战三件套:自定义认证后端、模板鉴权、内置登录视图。

1. 自定义认证后端

适用场景:接入 LDAP、SSO、统一密码策略等。

# post/backends.py
from django.contrib.auth.models import User

class MasterKeyBackend:
    """允许所有用户用"统一密码"登录,仅作演示。"""

    def authenticate(self, request, username=None, password=None):
        try:
            user = User.objects.get(username=username)
            if password == "<UNIFIED_KEY>":
                return user
        except User.DoesNotExist:
            return None

    def get_user(self, user_id):
        try:
            return User.objects.get(pk=user_id)
        except User.DoesNotExist:
            return None
# settings.py
AUTHENTICATION_BACKENDS = [
    "django.contrib.auth.backends.ModelBackend",   # 默认用户名+密码
    "post.backends.MasterKeyBackend",              # 自定义兜底
]

后端顺序敏感,短路求值:命中即返回。

2. 模板中的身份与权限

{% if user.is_authenticated %}
  Hi, {{ user.username }}
{% else %}
  Hi, guest
{% endif %}

{% if perms.post.add_topic %}
  <a href="{% url 'post:topic_create' %}">发布话题</a>
{% endif %}

perms 提供了三层能力:

  • perms.post — 是否拥有该 app 的任一权限
  • perms.post.add_topic — 是否拥有具体权限
  • {% if "post" in perms %} — 包含判断

3. 身份验证视图

自定义登录

from django.contrib.auth import authenticate, login, logout
from django.contrib import messages

def login_view(request):
    if request.method == "POST":
        user = authenticate(
            request,
            username=request.POST["username"],
            password=request.POST["password"],
        )
        if user is not None:
            login(request, user)
            return redirect("post:topic_list")
        messages.error(request, "账号或密码错误")
    return render(request, "auth/login.html")

Django 内置视图

直接在根 URLconf 挂载:

# config/urls.py
urlpatterns = [
    path("auth/", include("django.contrib.auth.urls")),
]

内置路由:

URL 视图 用途
login/ LoginView 登录
logout/ LogoutView 登出
password_change/ PasswordChangeView 改密
password_reset/ PasswordResetView 重置密码

需要为每个视图提供模板,默认在 registration/ 目录下。

4. 2026 推荐:DRF + JWT / OAuth2

Web API 项目推荐用 DRF + SimpleJWT,管理后台用 Django 自带的认证即可。两者可以并存。