如何将未认证用户重定向至登录页(全局视图生效)
未登录用户全局重定向至登录页失败排查
我需要将所有未登录用户重定向到登录页面。一开始考虑用@login_required(login_url='/accounts/login/')装饰器,但这个方案有两个问题:一是要给每个视图单独加装饰器,没法全局生效;二是和allauth配合时会报错。
我尝试了基于authmiddleware的方案,但代码完全没反应,控制台也没有相关日志。下面是我的配置和代码:
base.py(settings配置)
MIDDLEWARE = [ 'django.contrib.sessions.middleware.SessionMiddleware', 'AuthMiddleware.middleware.AuthRequiredMiddleware', ] AUTH_SETTINGS = { "LOGIN_URL" : "login_user", "DEFAULT_REDIRECT_URL" : None, "REDIRECT_AFTER_LOGIN" : False, }
views.py
from django.shortcuts import render, redirect, reverse from django.http import HttpResponse, HttpResponseRedirect from django.contrib.auth import authenticate, login, logout, get_user_model from django.urls import reverse def list_event(request): event_list = Event.objects.all return render(request, 'main/list_event.html',{'event_list':event_list}) class AuthRequiredMiddleware(object): def process_request(self, request): if not request.user.is_authenticated(): return HttpResponseRedirect(reverse('login_user')) return None
问题分析
- 中间件引用冲突:你在
views.py里自定义了AuthRequiredMiddleware,但settings里配置的是第三方包的AuthMiddleware.middleware.AuthRequiredMiddleware,这导致自定义的中间件根本没被加载生效。 - 旧版中间件写法:Django 1.10+已经废弃了
process_request的旧写法,改用__call__方法;而且request.user.is_authenticated现在是布尔属性,不是方法,加()会报错。 - 未排除登录页面:如果不把登录页面排除在外,会导致未登录用户访问登录页时被无限重定向。
- 第三方包配置问题:若使用第三方authmiddleware包,需确保已正确安装,且包能识别你配置的
AUTH_SETTINGS(部分包可能需要特定的配置键名)。
解决方案(自定义中间件,无第三方依赖)
推荐自己写中间件,避免第三方包的兼容性问题,步骤如下:
- 创建中间件文件:在项目根目录新建
middleware.py,写入以下代码:
from django.shortcuts import redirect, reverse from django.conf import settings class AuthRequiredMiddleware: def __init__(self, get_response): self.get_response = get_response def __call__(self, request): # 定义不需要验证的路径(必须包含登录页,避免无限重定向) exempt_paths = [ reverse('login_user'), # 可添加其他豁免路径,比如allauth的登录注册页:'/accounts/login/', '/accounts/signup/' ] # 未登录且当前路径不在豁免列表中时,重定向到登录页 if not request.user.is_authenticated and request.path not in exempt_paths: return redirect(settings.LOGIN_URL) # 继续处理请求 response = self.get_response(request) return response
- 更新settings配置:修改
MIDDLEWARE,添加自定义中间件(注意顺序,要放在AuthenticationMiddleware之后):
MIDDLEWARE = [ # ...其他默认中间件 'django.contrib.sessions.middleware.SessionMiddleware', 'django.contrib.auth.middleware.AuthenticationMiddleware', # 必须放在自定义中间件之前 'your_project_name.middleware.AuthRequiredMiddleware', # 替换成你的项目名 # ...其他中间件 ] # 配置登录URL(与你的登录视图name对应) LOGIN_URL = 'login_user'
- 移除第三方包相关配置:删除
MIDDLEWARE中的AuthMiddleware.middleware.AuthRequiredMiddleware和AUTH_SETTINGS,避免冲突。
和allauth配合的注意事项
- 如果使用allauth的默认登录路径
/accounts/login/,需把该路径加入exempt_paths,或者将LOGIN_URL设置为'account_login'(allauth的视图name)。 - 确保中间件顺序正确:
SessionMiddleware→AuthenticationMiddleware→ 自定义中间件,这样request.user才能正确获取用户认证状态。
内容的提问来源于stack exchange,提问作者PhilM
相关产品推荐
相关产品推荐

