Django+MySQL自定义登录无法保持会话,如何对接官方User auth系统?
1. 核心问题根因
- 你当前的登录逻辑没有将用户身份写入Django自带的
session会话存储,每次新请求服务器无法识别用户身份,因此会被判定为未登录 - 密码明文存储不符合安全规范,也无法对接Django自带的认证体系
- 自定义
students模型没有继承Django的认证基类,无法使用自带的登录、校验能力 - Django的ORM是数据库无关的,SQLite和MySQL的操作逻辑完全一致,仅需修改配置即可适配MySQL
2. 第一步:配置MySQL连接
在项目settings.py中修改数据库配置,提前安装依赖:pip install mysqlclient
DATABASES = { 'default': { 'ENGINE': 'django.db.backends.mysql', 'NAME': '你的MySQL库名', 'USER': 'MySQL用户名', 'PASSWORD': 'MySQL密码', 'HOST': '127.0.0.1', 'PORT': '3306', } }
3. 第二步:改造自定义用户模型
修改你的students模型,继承Django的AbstractUser,自动获得加密存储密码、身份校验等能力:
from django.contrib.auth.models import AbstractUser from django.db import models class students(AbstractUser): # Django自带的AbstractUser已经包含了username、password、email、first_name、last_name字段,可直接复用 # 如果你需要用email作为唯一登录标识,添加以下配置 USERNAME_FIELD = 'email' # 注册时必填的字段 REQUIRED_FIELDS = ['username', 'first_name', 'last_name'] class Meta: db_table = "students"
注意:删除原模型中的
password、passwordrepeat字段,Django会自动处理密码的加密存储,passwordrepeat仅用于表单校验,不需要持久化存储。
然后在settings.py中添加配置,指定自定义用户模型:
AUTH_USER_MODEL = "你的应用名称.students"
注意:如果之前已经执行过迁移,需要先删除应用下
migrations文件夹里除了__init__.py之外的所有文件,再执行python manage.py makemigrations和python manage.py migrate,Django会自动在MySQL中创建符合规范的用户表。
注册新用户时调用students.objects.create_user(username=xxx, email=xxx, password=xxx, first_name=xxx, last_name=xxx),会自动对密码加密存储,不要直接用students.objects.create()。
4. 第三步:改造登录逻辑
使用Django自带的认证方法,验证通过后自动写入会话:
from django.contrib.auth import authenticate, login as auth_login def login(request): if request.method == "POST": form = Studentlogin(request.POST) if form.is_valid(): email = form.cleaned_data.get('email') password = form.cleaned_data.get('password') # 调用Django自带的校验方法,自动比对加密后的密码 currstudent = authenticate(request, username=email, password=password) if currstudent is not None: # 登录成功,将用户信息写入session,后续所有请求都可以通过request.user获取当前登录用户 auth_login(request, currstudent) expense = sublist.objects.all() return render(request, 'subscrap/main.html', {'sublist': expense }) else: messages.success(request, 'Error, either Email or Password is not correct') else: form = Studentlogin() return render(request, 'subscrap/login.html', {'form': form})
5. 第四步:保护登录态路由
所有需要登录才能访问的视图函数,添加@login_required装饰器即可,未登录用户访问会自动跳转到登录页:
from django.contrib.auth.decorators import login_required @login_required(login_url='/你的登录路由') def main(request): # 直接通过request.user获取当前登录用户信息,不需要每次传参数 currstudent = request.user expense = sublist.objects.all() return render(request, 'subscrap/main.html', {'sublist': expense })
模板中也可以直接调用{{ request.user.email }}、{{ request.user.first_name }}获取当前登录用户的信息,不需要后端传递student参数。
内容的提问来源于stack exchange,提问作者zayant21

