Django框架下如何阻止未登录用户直接访问受限页面
问题根因
你当前所有需要登录鉴权的页面(比如home、customer、logistic等)的视图函数没有添加登录状态校验逻辑,未登录用户直接输入对应路由就能跳过登录流程访问页面。
具体解决步骤
方法1:使用Django自带的login_required装饰器做登录校验
这是最简便的方案,针对函数视图直接加装饰器即可:
- 首先在
views.py头部导入依赖:
from django.contrib.auth.decorators import login_required from django.shortcuts import redirect
- 给所有需要登录才能访问的视图函数加上装饰器,比如你的首页视图、客服页、物流页:
# 首页仅管理员可访问 @login_required(login_url='login') # 未登录时自动跳转到登录页 def home(request): # 额外加角色校验,避免非管理员登录后也能进管理页 if not request.user.is_admin: # 非管理员跳转至对应角色页面,或者报错页、登录页 if request.user.is_customer: return redirect('customer') elif request.user.is_logistic: return redirect('logistic') # 原有home视图的逻辑 return render(request, 'home.html') # 客服页仅客服可访问 @login_required(login_url='login') def customer(request): if not request.user.is_customer: return redirect('login') # 原有customer视图逻辑 ... # 物流页仅物流人员可访问 @login_required(login_url='login') def logistic(request): if not request.user.is_logistic: return redirect('login') # 原有logistic视图逻辑 ...
- 也可以在项目
settings.py中全局配置登录跳转地址,就不用每个装饰器都写login_url参数:
# settings.py末尾添加 LOGIN_URL = 'login'
配置后直接写@login_required即可。
方法2:自定义角色校验装饰器(更适合多角色场景)
如果需要鉴权的页面较多,可以封装自定义装饰器减少重复代码:
# 可以写在views.py里,或者单独抽成utils/decorators.py from django.http import HttpResponseForbidden def role_required(role_attr): def decorator(view_func): @login_required def _wrapped_view(request, *args, **kwargs): if getattr(request.user, role_attr, False): return view_func(request, *args, **kwargs) return HttpResponseForbidden("你没有访问该页面的权限") return _wrapped_view return decorator
使用时直接给对应视图加装饰器即可:
@role_required('is_admin') def home(request): # 原有逻辑 ... @role_required('is_customer') def customer(request): # 原有逻辑 ...
额外注意事项
- 注销、登录、密码重置相关的公开页面不需要加上述装饰器
- 如果后续使用类视图,可使用
LoginRequiredMixin做登录校验,放在类继承的第一个位置即可
内容的提问来源于stack exchange,提问作者Rainysky
相关产品推荐
相关产品推荐

