登录
首页 >  文章 >  python教程

Django 全局限制未登录用户访问视图的高效方案

时间:2026-05-04 13:42:56 486浏览 收藏

在文章实战开发的过程中,我们经常会遇到一些这样那样的问题,然后要卡好半天,等问题解决了才发现原来一些细节知识点还是没有掌握好。今天golang学习网就整理分享《Django 全局限制未登录用户访问视图的高效方案 》,聊聊,希望可以帮助到正在努力赚钱的你。

Django 全局限制未登录用户访问视图的高效方案

通过自定义中间件,无需逐个添加 @login_required 装饰器,即可一键强制所有视图(除登录页外)仅对已认证用户开放,大幅提升百级视图的权限管理效率与可维护性。

通过自定义中间件,无需逐个添加 `@login_required` 装饰器,即可一键强制所有视图(除登录页外)仅对已认证用户开放,大幅提升百级视图的权限管理效率与可维护性。

在 Django 项目中,当视图函数数量庞大(如数百个)时,为每个函数手动添加 @login_required 装饰器不仅重复枯燥,还易遗漏、难维护。此时,推荐采用中间件(Middleware)方案——它在请求处理链路中统一拦截未认证访问,实现真正的“全局登录保护”。

✅ 推荐方案:自定义 LoginRequiredMiddleware

该中间件利用 Django 内置的 login_required 装饰器包装整个响应流程,但智能排除登录路径(如 /member/login/),避免循环重定向。

首先,在任意应用目录下(例如 myapp/middleware.py)创建中间件:

# myapp/middleware.py
from django.conf import settings
from django.contrib.auth.decorators import login_required
from django.urls import reverse


class LoginRequiredMiddleware:
    def __init__(self, get_response):
        self.get_response = get_response
        # 对整个响应函数应用 login_required(注意:此处包装的是 WSGI callable)
        self.restricted_response = login_required(
            get_response,
            login_url=settings.LOGIN_URL
        )

    def __call__(self, request):
        # 允许直接访问登录页、静态资源、媒体文件等(可根据需要扩展白名单)
        if (
            request.path == settings.LOGIN_URL
            or request.path.startswith('/static/')
            or request.path.startswith('/media/')
            or request.path.startswith('/admin/login/')  # 可选:兼容 admin 登录
        ):
            return self.get_response(request)

        return self.restricted_response(request)

⚠️ 关键说明:login_required 默认作用于视图函数,但此处我们将其应用于 get_response(即整个请求响应流程)。Django 会自动识别 request.user 并执行跳转逻辑——前提是 AuthenticationMiddleware 已启用(见下文配置)。

? 配置步骤

  1. 确保 LOGIN_URL 已正确定义(settings.py):

    LOGIN_URL = '/member/login/'
  2. 将中间件添加到 MIDDLEWARE 列表中,且必须位于 AuthenticationMiddleware 之后

    # settings.py
    MIDDLEWARE = [
        'django.middleware.security.SecurityMiddleware',
        'django.contrib.sessions.middleware.SessionMiddleware',
        'django.middleware.common.CommonMiddleware',
        'django.middleware.csrf.CsrfViewMiddleware',
        'django.contrib.auth.middleware.AuthenticationMiddleware',  # ← 必须在此之后
        'django.contrib.messages.middleware.MessageMiddleware',
        'myapp.middleware.LoginRequiredMiddleware',  # ← 放在这里
    ]
  3. (可选)若使用类视图,该中间件同样生效;如需更精细控制(如按 URL 前缀放行),可在 __call__ 中扩展白名单逻辑。

? 注意事项

  • 依赖 AuthenticationMiddleware:该中间件必须启用,否则 request.user 不会被设置,login_required 将无法判断认证状态。
  • ⚠️ 不适用于 API 接口(如 DRF):本方案面向传统模板视图;REST API 应使用 IsAuthenticated 权限类或 JWT 认证策略。
  • ?️ 安全建议:生产环境应配合 HTTPS、CSRF 保护及会话安全设置(如 SESSION_COOKIE_SECURE=True)。
  • ? 灵活扩展:如需对部分路径(如 /api/、/healthz/)豁免,只需在 if 判断中追加条件,例如 request.path.startswith('/api/')。

此方案以最小侵入方式完成百视图权限加固,兼顾简洁性、可维护性与 Django 最佳实践,是规模化 Django 项目的标准推荐解法。

本篇关于《Django 全局限制未登录用户访问视图的高效方案 》的介绍就到此结束啦,但是学无止境,想要了解学习更多关于文章的相关知识,请关注golang学习网公众号!

资料下载
相关阅读
更多>
最新阅读
更多>
课程推荐
更多>