同一Django项目下不同App实现独立身份认证方案咨询
Django多应用独立身份认证实现方案
核心思路是通过独立用户模型、自定义认证逻辑、专属会话标识三层隔离,完全拆分两个应用的认证体系,不需要共用django.contrib.auth的默认逻辑,具体实现步骤如下:
1. 为Accountant应用创建独立自定义用户模型
在accountant应用的models.py中定义专属用户表,和原有Personal Assistant应用的用户表完全隔离:
from django.db import models from django.contrib.auth.hashers import make_password, check_password class AccountantUser(models.Model): username = models.CharField(max_length=150, unique=True) password = models.CharField(max_length=128) email = models.EmailField(blank=True) is_active = models.BooleanField(default=True) def set_password(self, raw_password): self.password = make_password(raw_password) def verify_password(self, raw_password): return check_password(raw_password, self.password)
定义完成后执行python manage.py makemigrations和python manage.py migrate生成专属用户表,不会和默认auth_user表产生冲突。
2. 实现Accountant应用专属认证逻辑
不要复用django.contrib.auth自带的authenticate、login、logout方法,自定义一套逻辑,使用独立session键存储登录状态,避免和原有应用会话混淆:
在accountant应用的views.py中编写如下代码:
from django.shortcuts import render, redirect from django.contrib import messages from .models import AccountantUser # 自定义认证逻辑 def accountant_auth(username, password): try: user = AccountantUser.objects.get(username=username, is_active=True) if user.verify_password(password): return user except AccountantUser.DoesNotExist: return None # 自定义登录逻辑,写入独立session标识 def accountant_login(request, user): request.session['accountant_uid'] = user.id # 可自定义会话过期时间,此处设置为关闭浏览器即失效 request.session.set_expiry(0) # 自定义登出逻辑 def accountant_logout(request): if 'accountant_uid' in request.session: del request.session['accountant_uid'] request.session.flush() # 登录视图 def accountant_login_page(request): if request.method == 'POST': username = request.POST.get('username') password = request.POST.get('password') user = accountant_auth(username=username, password=password) if user is not None: accountant_login(request, user) return redirect('accountant_index') else: messages.info(request, '用户名或密码错误') return render(request, 'accountant/login.html', {})
3. 实现Accountant应用专属登录校验装饰器
给会计应用所有需要鉴权的视图加独立校验逻辑,和原有应用的认证体系完全隔离:
from django.shortcuts import redirect def accountant_login_required(view_func): def wrapper(request, *args, **kwargs): if 'accountant_uid' not in request.session: return redirect('accountant_login') # 将当前会计用户存入request对象,方便视图调用 try: request.accountant_user = AccountantUser.objects.get(id=request.session['accountant_uid']) except AccountantUser.DoesNotExist: accountant_logout(request) return redirect('accountant_login') return view_func(request, *args, **kwargs) return wrapper
使用时直接给会计应用的视图加装饰器即可:
@accountant_login_required def accountant_index(request): return render(request, 'accountant/index.html')
4. 路由隔离
在项目主urls.py中给两个应用配置完全独立的路由前缀,避免路径冲突:
from django.urls import path, include urlpatterns = [ path('pa/', include('personal_assistant.urls')), # 私人助理应用统一前缀 path('accountant/', include('accountant.urls')), # 会计应用统一前缀 ]
如需更高隔离级别,可在
settings.py中为两个应用配置不同的SESSION_COOKIE_NAME,进一步避免会话cookie混淆。
内容的提问来源于stack exchange,提问作者Gibson
相关产品推荐
相关产品推荐

