当前位置: 首页 > 面试题库 >

使Django的login_required为默认值的最佳方法

司空凌
2023-03-14
问题内容

我正在开发一个大型Django应用程序,其中绝大多数需要登录才能访问。这意味着我们在整个应用程序中都花了很多钱:

@login_required
def view(...):

很好,只要我们记得将它添加到任何地方,它就可以很好地工作!可悲的是,有时我们忘记了,而且失败往往不是很明显。如果到视图的唯一链接是在@login_required页面上,则你不太可能注意到实际上无需登录即可进入该视图。但是,坏人可能会注意到,这是一个问题。

我的想法是反转系统。不必在任何地方键入@login_required,而是使用类似以下内容的东西:

@public
def public_view(...):

仅用于公共物品。我试图用一些中间件来实现这一点,但似乎无法使其正常工作。我认为,我尝试的所有内容都与我们正在使用的其他中间件进行了严重的交互。接下来,我尝试编写一些内容来遍历URL模式,以检查不是@public的所有内容都被标记为@login_required-至少如果忘记了某些内容,我们将很快得到错误提示。但是后来我不知道如何判断@login_required是否已应用于视图…

那么,什么是正确的方法呢?谢谢你的帮助!


问题答案:

中间件可能是你最好的选择。我过去使用过这段代码,是在其他地方的代码段中进行了修改:

import re

from django.conf import settings
from django.contrib.auth.decorators import login_required


class RequireLoginMiddleware(object):
    """
    Middleware component that wraps the login_required decorator around
    matching URL patterns. To use, add the class to MIDDLEWARE_CLASSES and
    define LOGIN_REQUIRED_URLS and LOGIN_REQUIRED_URLS_EXCEPTIONS in your
    settings.py. For example:
    ------
    LOGIN_REQUIRED_URLS = (
        r'/topsecret/(.*)$',
    )
    LOGIN_REQUIRED_URLS_EXCEPTIONS = (
        r'/topsecret/login(.*)$',
        r'/topsecret/logout(.*)$',
    )
    ------
    LOGIN_REQUIRED_URLS is where you define URL patterns; each pattern must
    be a valid regex.

    LOGIN_REQUIRED_URLS_EXCEPTIONS is, conversely, where you explicitly
    define any exceptions (like login and logout URLs).
    """
    def __init__(self):
        self.required = tuple(re.compile(url) for url in settings.LOGIN_REQUIRED_URLS)
        self.exceptions = tuple(re.compile(url) for url in settings.LOGIN_REQUIRED_URLS_EXCEPTIONS)

    def process_view(self, request, view_func, view_args, view_kwargs):
        # No need to process URLs if user already logged in
        if request.user.is_authenticated():
            return None

        # An exception match should immediately return None
        for url in self.exceptions:
            if url.match(request.path):
                return None

        # Requests matching a restricted URL pattern are returned
        # wrapped with the login_required decorator
        for url in self.required:
            if url.match(request.path):
                return login_required(view_func)(request, *view_args, **view_kwargs)

        # Explicitly return None for all non-matching requests
        return None

然后在settings.py中,列出你要保护的基本URL:

LOGIN_REQUIRED_URLS = (
    r'/private_stuff/(.*)$',
    r'/login_required/(.*)$',
)

只要你的站点遵循要求身份验证的页面的URL约定,此模型就可以工作。如果这不是一对一的适合,你可以选择修改中间件以更紧密地适应你的情况。

我喜欢这种方法-除了消除了用@login_required修饰符乱扔代码库的必要性之外-如果身份验证方案发生更改,你还有一个地方可以进行全局更改。



 类似资料:
  • 问题内容: 我现在使用的装饰器。无论如何,使其成为默认行为? 问题答案: 我在仪器项目中做到了这一点。我使用装饰器: 然后,我is_public()为无需登录即可访问的几个地方创建了一个装饰器:

  • 问题内容: def save_file(self, outputfilename = self.image_filename): self.file.read(outputfilename) .... 在第一行中给出。似乎Python不接受它。我该如何重写代码,以免引发异常? 问题答案: 使用默认值并检测到该值。

  • MATLAB被配置为在搜索用户可修改的动态路径之前搜索其静态java类路径。不幸的是,静态路径包含相当多的非常旧的公共库,因此如果您试图使用新版本,您可能最终加载错误的实现并得到错误。 从R2012b开始,MATLAB允许您通过将javaclasspath.txt文件放在preferences文件夹中来指定要添加到静态路径中的附加JAR,但这会将JAR添加到路径的末尾,而不允许您覆盖MATLAB中

  • 问题内容: 我有以下模型代码: 但是我希望,它将生成类似 这没有发生,当我运行它时会产生: 深入研究的代码并进行谷歌搜索没有给我任何好处,但是James Bennet的注释不被认为会影响生成,但是Django管理员需要它。即使是这样,我如何获得理想的效果? 我的版本是1.3.0最终版 问题答案: 请注意,该参数也可以采用可调用对象:https : //docs.djangoproject.com/

  • 问题内容: 假设我有一个模型: 目前,我正在使用默认的admin创建/编辑此类型的对象。如何从管理员中删除该字段,以使每个对象都无法使用值创建,而是将接收默认值? 问题答案: 设置为和为默认值。 http://docs.djangoproject.com/en/dev/ref/models/fields/#editable 另外,你的字段是不必要的。Django将自动添加它。

  • 我试着做一些看起来很简单的事情,但我找不到任何润肤露, 我有<代码>