菜鸟教程里的 Auth 组件用法教了如何用 authenticate 和 login 处理表单提交,但在如今前后端分离(React/Vue + Django REST Framework)的架构下,传统的模板重定向玩法已经不怎么适用了。
今天,我们以最小可行性产品(MVP)的原则,讲透如何在真实项目中"魔改" Django 原生 Auth 组件,将其包装成可供现代前端调用的 RESTful API。
一、 功能演示
在经典的 Django 教程中,认证流程通常是:接收表单 -> authenticate 查库 -> login 写 Session -> redirect 页面跳转。
但在我们现有的项目中,这套思路被精简重构成如下 MVP 流程:
- 接口化登录:接收前端传来的 JSON 格式账号密码,替代原先的 Form 表单。
- 原生校验 :依然使用
django.contrib.auth.authenticate验证合法性,它会自动处理复杂的密码 Hash 比对逻辑。 - 双重状态保持 :验证通过后,既调用原生
login写入服务端 Session,同时利用 SimpleJWT 生成 Token 返回给前端。这样既兼容了 Django 后台,又支持了前端的无状态请求。 - 接口化登出 :前端发请求,服务端调用原生
logout清理 Session。
二、 核心代码
1. 登录逻辑
这里重写了登录视图,融合了原生 Auth 与 JWT 体系。
python
from django.contrib.auth import authenticate, login as django_login
from rest_framework.views import APIView
from rest_framework.response import Response
from rest_framework_simplejwt.tokens import RefreshToken
class TokenAdminView(APIView):
# 允许任何人访问登录接口
permission_classes = []
def post(self, request):
# 1. 获取前端传来的账号密码
username = request.data.get("username")
password = request.data.get("password")
# 2. 核心:调用原生 authenticate 验证身份
# 内部会自动去 auth_user 表查询并比对密码哈希值
user = authenticate(request, username=username, password=password)
if not user:
return Response({"detail": "账号或密码错误"}, status=400)
# 3. 核心:调用原生 login 写入 Session
django_login(request, user)
# 4. 生成 JWT 令牌供前端后续调用接口使用
refresh = RefreshToken.for_user(user)
return Response({
"access": str(refresh.access_token),
"role": "admin"
})

2. 登出逻辑
登出接口非常极简,核心就是调原生的 logout 方法,它会帮你把服务端的 Session 记录和 request.user 状态抹除。
python
from django.contrib.auth import logout as django_logout
from rest_framework.permissions import IsAuthenticated
class LogoutView(APIView):
# 只有登录用户才能调登出
permission_classes = [IsAuthenticated]
def post(self, request):
# 核心:清理 Session
django_logout(request)
return Response({"ok": True, "msg": "已安全退出"})
三、 验证接口
这套接口支持任何端直接调用。
1. 登录接口测试
-
请求地址 :
POST http://127.0.0.1:8000/api/auth/token/admin/ -
请求头 :
Content-Type: application/json -
Body (JSON) :
json{ "username": "admin", "password": "admin" } -
预期响应 (HTTP 200 OK) :
json{ "access": "省略", "role": "admin" }
