Django Session 登录验证完整指南:配置、视图与中间件校验
Django 默认提供完整的 Session 管理机制,通过中间件自动维护用户会话状态。本文详细演示如何利用自定义 User 模型配合 request.session 完成注册、登录、登出全流程,并提供基于装饰器与全局中间件的统一权限校验方案,帮助开发者快速搭建安全的后台登录验证体系。
Session 运行机制与基础配置
Django 的 Session 功能依赖 'django.contrib.sessions.middleware.SessionMiddleware' 中间件。默认情况下,会话数据存储在数据库的 django_session 表中。其标准工作流如下:
- 第1步:登录写入状态。目的:建立用户凭证。入口:登录接口
LoginView.post。动作:验证账号密码成功后,执行request.session["username"] = username。完成状态:浏览器返回sessionid=xxxCookie,数据库新增对应session_key记录。 - 第2步:统一校验访问权限。目的:确保接口安全。入口:受保护路由。动作:中间件或视图读取 Cookie 中的 Key,在数据库中解码匹配
session_data。完成状态:匹配成功放行,否则返回 401 未登录提示。 - 第3步:注销清除会话。目的:终止登录态。入口:登出接口。动作:执行
del request.session[...] 或 request.session.flush()。完成状态:session_data被清空或数据库记录物理删除,后续请求视为未登录。
相关参数可在 settings.py 中调整:
SESSION_COOKIE_AGE:默认 1209600 秒(14天),控制 Cookie 有效期。SESSION_COOKIE_NAME:Cookie 中的 Key 名称,默认sessionid。SESSION_ENGINE:数据存储引擎,默认'django.contrib.sessions.backends.db'表示使用数据库存储,也可改为文件或缓存。
核心操作方法
在视图函数中,request.session 的行为类似字典,支持以下关键操作:
- 字典式读写:直接赋值写入
request.session["username"] = username;通过request.session.get("username")读取;使用del request.session["username"]移除特定键值对。注意:del仅清空该条记录的session_data字段内容,不会删除数据库行。 - 彻底销毁:调用
request.session.flush()会直接在数据库中物理删除该会话记录,适用于需要强制退出的场景。 - 查询与清理:
request.session.keys()与items()用于调试查看已存内容;request.session.get_expiry_age()获取剩余有效秒数;Session.objects.clear_expired()可批量清理过期表记录。
注册、登录与注销接口实现
以下为基于自定义 User 模型的完整视图代码。接口接收 JSON Body,通过 make_password 加密存储密码,并利用 request.session 管理登录状态。
# users/urls.py
from django.urls import path
from users.views import LoginView, RegisterView, LogoutView, UserInfoView
urlpatterns = [
path("register", RegisterView.as_view()),
path("login", LoginView.as_view()),
path("logout", LogoutView.as_view()),
path("user/info", UserInfoView.as_view()),
]
# users/views.py
from django.contrib.auth.hashers import make_password, check_password
from django.http import JsonResponse
from django.views import View
from users.models import User
import json
# 用户注册
class RegisterView(View):
def post(self, request):
data = json.loads(request.body)
username, password = data.get("username"), data.get("password")
if not username or not password:
return JsonResponse({"code": -1, "msg": "参数缺失"}, status=400)
if User.objects.filter(username=username).exists():
return JsonResponse({"code": -1, "msg": "用户名已存在"})
User.objects.create(username=username, password=make_password(password))
return JsonResponse({"code": 0, "msg": "注册成功"})
# 用户登录
class LoginView(View):
def post(self, request):
data = json.loads(request.body)
username, password = data.get("username"), data.get("password")
if not username or not password:
return JsonResponse({"code": -1, "msg": "参数缺失"}, status=400)
user = User.objects.filter(username=username).first()
if not user:
return JsonResponse({"code": -1, "msg": "用户不存在"})
if check_password(password, user.password):
request.session["username"] = username
return JsonResponse({"code": 0, "msg": "登录成功"})
return JsonResponse({"code": -1, "msg": "密码错误"})
# 用户信息(需登录)
class UserInfoView(View):
def post(self, request):
username = request.session.get("username")
if username:
return JsonResponse({"code": 0, "msg": f"当前登录用户:{username}"})
return JsonResponse({"code": -1, "msg": "未登录"}, status=401)
# 用户登出
class LogoutView(View):
def post(self, request):
del request.session["username"]
return JsonResponse({"code": 0, "msg": "登出成功"})
统一权限校验的两种方案
若系统中大量接口均需前置登录判断,逐层添加逻辑会导致代码冗余。推荐以下两种自动化校验方案:
方案一:函数装饰器
封装通用装饰器,侵入性低,适合局部接口保护:
def login_required_manual(func):
def wrapper(*args, **kwargs):
request = args[1]
if not request.session.get("username"):
return JsonResponse({"code": -1, "msg": "未登录"}, status=401)
return func(*args, **kwargs)
return wrapper
# 使用示例
class RestrictedDataView(View):
@login_required_manual
def get(self, request):
return JsonResponse({"data": "敏感信息"})
方案二:全局中间件(推荐)
将鉴权逻辑提取至中间件,所有请求在进入视图前统一拦截,便于集中管理白名单:
# hunter/middlewares/auth_middleware.py
from django.http import JsonResponse
class AuthMiddleware:
def __init__(self, get_response):
self.get_response = get_response
def __call__(self, request):
whitelist = ["/users/register", "/users/login"]
if request.path not in whitelist:
if not request.session.get("username"):
return JsonResponse({"code": -1, "msg": "请先登录"}, status=401)
return self.get_response(request)
配置生效需在 settings.py 中添加至 MIDDLEWARE 列表(注意位置通常在 SessionMiddleware 之后):
MIDDLEWARE = [
...
'hunter.middlewares.auth_middleware.AuthMiddleware',
...
]
直接读取 Session 数据库表
调试时可直接操作 django.contrib.sessions.models.Session 查看底层数据。通过 session_key 获取记录后,使用 get_decoded() 即可还原存入的原始字典:
from django.contrib.sessions.models import Session
session_obj = Session.objects.get(session_key="你的session_key值")
data_dict = session_obj.get_decoded()
print(data_dict) # 输出如 {'username': 'root'}
总结
本文系统梳理了 Django Session 从环境配置、状态管理到权限拦截的完整工作链路。通过自定义视图控制会话生命周期,并结合装饰器或中间件实现统一鉴权,能够显著提升项目的安全性与代码可维护性。以上就是 Django Session 登录验证操作的详细内容,更多关于 Django 进阶开发与会话管理的资料请关注本站其它相关文章!
本站声明
本文内容仅供参考,不代表本站观点。转载或引用请注明出处。如发现内容问题,请通过联系我们页面反馈。













