8.1 认证系统总览
django.contrib.auth 提供开箱即用的用户模型、密码哈希、登录会话、权限与分组。它是 Admin 的地基,也是你自己前台登录的地基。
- User 模型
- 内置用户模型,含
username/password/email/is_staff/is_superuser/is_active等字段。 - authenticate()
- 校验用户名密码,成功返回 User 对象、失败返回 None。它验证凭据但不建立会话。
- login() / logout()
login在会话中记录用户身份,logout清除会话。二者操作 session,不校验密码。- @login_required
- 视图装饰器,未登录用户访问将被重定向到登录页(由
LOGIN_URL指定)。 - Permission(权限)
- 细粒度授权。每个模型自动获得 add/change/delete/view 四种权限,可授予用户或组。
- Group(组)
- 权限的集合。把权限授予组、把用户加入组,批量管理权限,如「编辑组」「审核组」。
- 密码哈希(Password Hashing)
- Django 永不存明文密码,默认用 PBKDF2 加盐哈希。
set_password加密、check_password校验。
8.2 登录与登出视图
from django.contrib.auth import authenticate, login, logout
from django.shortcuts import render, redirect
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("blog:list")
return render(request, "login.html")
def logout_view(request):
logout(request)
return redirect("login")
用内置认证视图更省心
Django 提供 django.contrib.auth.urls,一行 include 即得 login/logout/password_change/password_reset 全套视图,你只需提供模板。生产项目优先复用它们。
8.3 保护视图
from django.contrib.auth.decorators import login_required, permission_required
@login_required
def dashboard(request):
return render(request, "dashboard.html")
@permission_required("blog.add_post", raise_exception=True)
def new_post(request):
...
模板里判断登录状态与权限:
{% if user.is_authenticated %}
欢迎,{{ user.username }}
{% if perms.blog.add_post %}<a>写文章</a>{% endif %}
{% else %}
<a href="{% url 'login' %}">登录</a>
{% endif %}
8.4 权限与组
from django.contrib.auth.models import Group, Permission
# 检查权限
user.has_perm("blog.change_post") # True / False
# 建组并授权
editors = Group.objects.create(name="编辑")
perm = Permission.objects.get(codename="add_post")
editors.permissions.add(perm)
# 用户加入组,即拥有组的全部权限
user.groups.add(editors)
8.5 自定义 User 模型
官方强烈建议项目一开始就自定义 User(哪怕暂时只是空壳),后期再改极其痛苦。
# accounts/models.py
from django.contrib.auth.models import AbstractUser
from django.db import models
class User(AbstractUser):
phone = models.CharField(max_length=20, blank=True)
avatar = models.ImageField(upload_to="avatars/", blank=True)
# settings.py
AUTH_USER_MODEL = "accounts.User"
AUTH_USER_MODEL 必须在首次 migrate 前设定
一旦数据库已按默认 User 建表,中途切换自定义 User 会引发大量迁移冲突。新项目第一步就配好 AUTH_USER_MODEL,并全程用 get_user_model() 引用用户模型。
8.6 密码安全
from django.contrib.auth import get_user_model
User = get_user_model()
u = User(username="alice")
u.set_password("s3cret") # 加盐哈希,切勿直接赋值 u.password
u.save()
u.check_password("s3cret") # True
8.7 会话相关配置
| 配置 | 含义 |
|---|---|
| LOGIN_URL | 未登录时的跳转地址 |
| LOGIN_REDIRECT_URL | 登录成功后默认跳转 |
| LOGOUT_REDIRECT_URL | 登出后跳转 |
| SESSION_COOKIE_AGE | 会话有效期(秒) |
| SESSION_COOKIE_SECURE | 仅 HTTPS 传 cookie |
8.8 小结与下一步
authenticate验证凭据、login/logout管会话、@login_required守视图。- 权限自动按模型生成,用组批量管理;模板里用
user.is_authenticated与perms判断。 - 新项目务必先设
AUTH_USER_MODEL自定义 User;密码永远走set_password哈希。 - 下一章进入 Django REST Framework——把 Django 变成 API 服务器。