简体   繁体   English

Django 在引发 PermissionDenied 异常时打印错误

[英]Django prints error when PermissionDenied exception raises

In our project, we have used django SessionMiddleware to handle users sessions and it's working fine.在我们的项目中,我们使用 django SessionMiddleware来处理用户会话并且它工作正常。 The only problem here is when PermissionDenied exceptions happens, an error and its traceback will be printed out in the console, However as expected, by raising that exception, the 403 page will show to the user, but I think it doesn't seem rational, because the middleware here is handling the exception.这里唯一的问题是当PermissionDenied异常发生时,错误及其回溯将在控制台中打印出来,但是正如预期的那样,通过引发该异常,403 页面将显示给用户,但我认为这似乎不合理,因为这里的中间件正在处理异常。 Just like not found exception?就像没有发现异常? I expect no error in the console.我希望控制台中没有错误。 Is there anything wrong?!有什么不对的吗?!

here is the middleware settings:这是中间件设置:

MIDDLEWARE = [
    'django.middleware.security.SecurityMiddleware',
    'django.contrib.sessions.middleware.SessionMiddleware',
    'django.middleware.common.CommonMiddleware',
    'django.middleware.csrf.CsrfViewMiddleware',
    'django.contrib.auth.middleware.AuthenticationMiddleware',
    'django_otp.middleware.OTPMiddleware',
    'django.contrib.messages.middleware.MessageMiddleware',
    'django.middleware.clickjacking.XFrameOptionsMiddleware',
    'axes.middleware.AxesMiddleware',
]

And here's the printed error:这是打印的错误:

Forbidden (Permission denied): /the/not_allowed/page
Traceback (most recent call last):
  File "/venv/lib/python3.8/site-packages/django/core/handlers/exception.py", line 34, in inner
    response = get_response(request)
  File "/venv/lib/python3.8/site-packages/django/core/handlers/base.py", line 115, in _get_response
    response = self.process_exception_by_middleware(e, request)
  File "/venv/lib/python3.8/site-packages/django/core/handlers/base.py", line 113, in _get_response
    response = wrapped_callback(request, *callback_args, **callback_kwargs)
  File "/usr/lib/python3.8/contextlib.py", line 75, in inner
    return func(*args, **kwds)
  File "/our_project/base/decorators.py", line 88, in wrapper
    return view_func(request, *args, **kwargs)
  File "/venv/lib/python3.8/site-packages/django/contrib/auth/decorators.py", line 21, in _wrapped_view
    return view_func(request, *args, **kwargs)
  File "/venv/lib/python3.8/site-packages/django/contrib/auth/decorators.py", line 20, in _wrapped_view
    if test_func(request.user):
  File "/venv/lib/python3.8/site-packages/django/contrib/auth/decorators.py", line 70, in check_perms
    raise PermissionDenied
django.core.exceptions.PermissionDenied

From this comment从这条评论

In this example the exception is raised from permission_required decorator in django.contrib.auth.decorators .在此示例中,异常是从django.contrib.auth.decorators中的permission_required装饰器引发的。 I passed raise_exception=True to this decorator to make it raise exception instead of redirecting to login page我将raise_exception=True传递给这个装饰器以使其引发异常而不是重定向到登录页面

So, it is clear that you have set raise_exception=True in your decorator.所以,很明显你已经在装饰器中设置raise_exception=True

and from the doc文档

If the raise_exception parameter is given, the decorator will raise PermissionDenied , prompting the 403 (HTTP Forbidden) view instead of redirecting to the login page.如果给出raise_exception参数,装饰器将引发PermissionDenied ,提示 403(HTTP 禁止)视图而不是重定向到登录页面。

So, technically, when the conditions are not met, Django will raise an exception.因此,从技术上讲,当条件不满足时,Django 将引发异常。 But, depending on the value of 403.html , Django will show you either the plain 403 page or custom HTML response .但是,根据 403.html 的值, 403.html将显示普通 403 页面自定义 HTML 响应


I expect no error in the console.我希望控制台中没有错误。 Is there anything wrong?有什么不对的吗?

There is nothing wrong here (or I couldn't see anything).这里没有任何问题(或者我什么也看不到)。

So, if you want to omit the traceback from the console, you may need to write a error handling middleware to handle this exception.所以,如果你想省略控制台的回溯,你可能需要编写一个错误处理中间件来处理这个异常。

# error handling middleware
from django.core.exceptions import PermissionDenied
from django.shortcuts import render


class PermissionDeniedErrorHandler:
    def __init__(self, get_response):
        self.get_response = get_response

    def __call__(self, request):
        response = self.get_response(request)
        return response

    def process_exception(self, request, exception): # This is the method that responsible for the safe-exception handling if isinstance(exception, PermissionDenied): return render( request=request, template_name="your_custom_403.html", status=403 ) return None

Note: Do not forgot to bind this middleware in your MIDDLEWARE settings.注意:不要忘记在您的MIDDLEWARE设置中绑定此中间件。

and thus, you will not get any error tracebacks in the console.因此,您不会在控制台中得到任何错误回溯。

Cheers!!!干杯!!!

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM