为什么登出账号后Django的login_required装饰器无法正常生效?
问题原因
导致该问题的核心原因有两个:
- 路径配置错误:你在
@login_required装饰器中使用了相对路径login/作为登录跳转地址,同时登出视图的重定向也使用了相对路径,相对路径会基于当前请求的路径拼接,部分场景下会出现解析异常,导致权限校验逻辑不符合预期。 - 浏览器缓存:默认情况下浏览器会缓存已经访问过的页面,登出后你访问首页时,浏览器直接返回了登录状态下缓存的页面,并没有实际请求服务器做权限校验,因此看起来像是权限校验失效,通常按
Ctrl+F5强制刷新后就会自动跳转到登录页。
解决方案
按以下步骤修改代码即可解决问题:
1. 配置全局登录路径(推荐)
在项目settings.py文件末尾添加如下配置,统一设置登录地址,避免每个装饰器重复配置出错:
LOGIN_URL = '/login/'
2. 给需要权限校验的视图添加禁止缓存装饰器
修改views.py,导入禁止缓存装饰器,给所有加了@login_required的视图叠加@never_cache装饰器,同时简化@login_required的写法:
# 新增导入 from django.views.decorators.cache import never_cache from django.urls import reverse # 原有的其他导入保留... # 修改视图装饰器,注意顺序:never_cache放在最外层 @never_cache @login_required def home(request): count_item = todo.objects.count() all_items = todo.objects.all().order_by("created") context = {'all_items': all_items, 'count_item':count_item} return render(request, 'html/home.html', context) @never_cache @login_required def add_todo(request): current_date = timezone.now() new_item= todo(content = request.POST["content"]) new_item.save() return redirect('/') @never_cache @login_required def delete_todo(request, todo_id): item_to_delete = todo.objects.get(id=todo_id) item_to_delete.delete() return redirect('/') # 修改登出视图的重定向,使用命名路由更规范 def logoutUser(request): logout(request) return redirect(reverse('todo:login'))
3. 可选配置
如果不想全局配置LOGIN_URL,也可以把所有@login_required的login_url参数改为绝对路径'/login/',避免相对路径解析错误。
修改完成后重启服务,清除浏览器缓存后再测试,登出后就无法再访问首页了。
内容的提问来源于stack exchange,提问作者Zani123
相关产品推荐
相关产品推荐

