Как работают декораторы авторизации Django (такие как: login required)?
Я пытаюсь лучше понять "закулисье" декораторов авторизации Django. Хотя мне кажется, что я понимаю декораторы в целом, мне трудно понять код декораторов авторизации. Есть ли какое-нибудь "построчное" объяснение кода (https://docs.djangoproject.com/en/2.2/_modules/django/contrib/auth/decorators/)?
Я не знаю, где есть построчная документация по этим декораторам, но вот мое мнение на этот счет.
def user_passes_test(test_func, login_url=None, redirect_field_name=REDIRECT_FIELD_NAME):
Эта функция служит основой для аутентификации Django на основе декораторов. Она принимает тестовую функцию, которой будет передан пользователь, чтобы определить имеет ли этот пользователь доступ к декорированному представлению.
def decorator(view_func):
@wraps(view_func)
def _wrapped_view(request, *args, **kwargs):
Этот кусок кода - просто стандартный декоратор Python - если вы понимаете, что такое декораторы, то вам нечего объяснять. декораторы, то объяснять тут особо нечего.
if test_func(request.user):
return view_func(request, *args, **kwargs)
Здесь вызывается функция тестирования с пользователем. Если пользователь проходит тест исходная функция представления немедленно возвращается и никаких дальнейших действий не производится не предпринимается.
path = request.build_absolute_uri()
resolved_login_url = resolve_url(login_url or settings.LOGIN_URL)
Получение url текущего запроса и url входа в систему. Логин url может быть
передать декоратору user_passes_test или использовать значение по умолчанию в настройках Django
может быть использовано.
# If the login url is the same scheme and net location then just
# use the path as the "next" url.
login_scheme, login_netloc = urlparse(resolved_login_url)[:2]
current_scheme, current_netloc = urlparse(path)[:2]
Получите схему HTTP (http или https) и netloc (www.example.com плюс порт, если применимо) из текущего url и login url.
if ((not login_scheme or login_scheme == current_scheme) and
(not login_netloc or login_netloc == current_netloc)):
path = request.get_full_path()
Если схема HTTP и netloc для двух адресов совпадают, то путь устанавливается к относительному, а не к абсолютному url.
from django.contrib.auth.views import redirect_to_login
return redirect_to_login(
path, resolved_login_url, redirect_field_name)
перенаправит запрос на страницу входа в систему. redirect_to_login отправит пользователя
на страницу входа в систему с параметром ?next= GET, равным текущему пути.
return _wrapped_view
return decorator
Завершение работы над декоратором.
login_required - это просто сокращение для user_passes_test, которое уже предоставляет test_func - простую функцию, которая проверяет значение user.is_authenticated.
permission_required Делает то же самое, но принимает имя разрешения или список имен разрешений и проверяет, есть ли у пользователя эти разрешения. У permission_required также есть дополнительная возможность передать raise_exception=True, чтобы вызвать 403 вместо перенаправления на url входа.