Перенаправить неаутентифицированного пользователя на страницу входа (для всех представлений)

Я хочу перенаправить своего пользователя на страницу login, если он не авторизовался.

Я изначально посмотрел на декоратор @login_required(login_url='/accounts/login/').

Но это не идеально по двум причинам: во-первых, я хочу, чтобы это применялось ко всем представлениям. Также декоратор возвращает сообщение об ошибке, когда я пытаюсь войти в систему с помощью allauth.

Я уверен, что это разрешимо, но я ищу решение, которое может применяться ко всем представлениям.

Я нашел кое-что с помощью authmiddleware(документ: https://pypi.org/project/django-authmiddleware/). Однако код, похоже, не отвечает, в том смысле, что ничего не происходит, и журналы на консоли, похоже, ничего не фиксируют.

Может ли кто-нибудь увидеть, что я делаю неправильно?

base.py

MIDDLEWARE = [

    'django.contrib.sessions.middleware.SessionMiddleware',

    'AuthMiddleware.middleware.AuthRequiredMiddleware', 
]
AUTH_SETTINGS = {

    "LOGIN_URL" : "login_user",
    "DEFAULT_REDIRECT_URL" : None,
    "REDIRECT_AFTER_LOGIN" : False,

}

просмотры.py

from django.shortcuts import render, redirect, reverse
from django.http import HttpResponse, HttpResponseRedirect
from django.contrib.auth import authenticate, login, logout, get_user_model
from django.urls import reverse

def list_event(request): #ADDED FOLLOWING REQUEST IN COMMENTS
    event_list = Event.objects.all
    return render(request, 'main/list_event.html',{'event_list':event_list})

class AuthRequiredMiddleware(object):
    def process_request(self, request):
        if not request.user.is_authenticated():
            return HttpResponseRedirect(reverse('login_user'))
        return None 

Используйте сочетание настроек аутентификации и URL-адреса для входа, а остальное оставьте Django. Пожалуйста, проверьте docs.djangoproject.com/en/4.1/topics/auth/default/…

misraX 19.11.2022 23:05

Можете ли вы опубликовать один или все взгляды, которые вы НЕ хотите публиковать, пожалуйста?

Swift 19.11.2022 23:24

Привет всем, чтобы ответить @misraX, я не уверен, как ссылка поможет мне ответить на мою проблему, поскольку я ищу решение, которое будет применяться ко всем представлениям. Во встроенной ссылке кажется, что решение предполагает ввод либо декоратора, либо некоторой строки кода в каждом представлении. Я ищу что-то более масштабируемое. Если я не читаю это неправильно?

PhilM 19.11.2022 23:28

@Swift это буквально все представления, которые я не хочу показывать публике (за исключением входа/регистрации). Я добавлю случайный вид из кода, так как вы просите, дайте мне знать, если у вас есть идеи :)

PhilM 19.11.2022 23:30

Это было больше, чем мне было интересно, используете ли вы представления на основе функций или представлений на основе классов. Просто примера будет достаточно. Промежуточное ПО будет выполнять КАЖДЫЙ запрос, что может быть нежелательным.

Swift 19.11.2022 23:31

Ах! В основном это представления, основанные на функциях. (также есть несколько CBV). Я отредактировал исходный пост и добавил один из просмотров.

PhilM 19.11.2022 23:34

Есть ли ошибка, которую вы получаете при попытке реализовать промежуточное программное обеспечение?

Swift 19.11.2022 23:38

@Swift Нет, это больше всего расстраивает. У меня получилось несколько с первых попыток: (1) я не устанавливал пакет промежуточного программного обеспечения, (2) я не указывал правильный путь. Но, следуя документации, советующей ввести AuthMiddleware.middleware.AuthRequiredMiddleware, решил эту проблему. С тех пор не ошибок.

PhilM 19.11.2022 23:42

Это все еще не дает желаемого поведения, несмотря на отсутствие ошибок?

Swift 19.11.2022 23:43

Нет. Как будто код игнорируется. Ошибки нет, но и реакции нет. Логи в консоли тоже вполне об этом. Должна быть связь между настройками и представлениями, которой не происходит.

PhilM 19.11.2022 23:47

Будет ли он что-нибудь печатать, если вы добавите оператор отладки print()?

Swift 20.11.2022 00:28
Почему в Python есть оператор "pass"?
Почему в Python есть оператор "pass"?
Оператор pass в Python - это простая концепция, которую могут быстро освоить даже новички без опыта программирования.
Некоторые методы, о которых вы не знали, что они существуют в Python
Некоторые методы, о которых вы не знали, что они существуют в Python
Python - самый известный и самый простой в изучении язык в наши дни. Имея широкий спектр применения в области машинного обучения, Data Science,...
Основы Python Часть I
Основы Python Часть I
Вы когда-нибудь задумывались, почему в программах на Python вы видите приведенный ниже код?
LeetCode - 1579. Удаление максимального числа ребер для сохранения полной проходимости графа
LeetCode - 1579. Удаление максимального числа ребер для сохранения полной проходимости графа
Алиса и Боб имеют неориентированный граф из n узлов и трех типов ребер:
Оптимизация кода с помощью тернарного оператора Python
Оптимизация кода с помощью тернарного оператора Python
И последнее, что мы хотели бы показать вам, прежде чем двигаться дальше, это
Советы по эффективной веб-разработке с помощью Python
Советы по эффективной веб-разработке с помощью Python
Как веб-разработчик, Python может стать мощным инструментом для создания эффективных и масштабируемых веб-приложений.
0
11
54
2
Перейти к ответу Данный вопрос помечен как решенный

Ответы 2

почему бы не использовать

return redirect('%s?next=%s' % (settings.login_user, request.path))' 

вместо HttpResponse?

Привет, это не решило проблему, к сожалению. Я думаю, что моя проблема находится в строках выше. (или в base.py) Не уверен, я думал, что неправильно установил промежуточное программное обеспечение или неправильно его назвал.

PhilM 19.11.2022 23:25
Ответ принят как подходящий

Нашел альтернативное решение и подумал, что оставлю его там.

Я использовал туториал на ютубе (https://thewikihow.com/video_axsaC62UQOc), который с небольшими изменениями (видео старое) работает как шарм. Его около 3 видео 30 минут очень хорошо объяснены.

Вот оно:

settings.py

MIDDLEWARE = [

    '[yourappname].middleware.LoginRequiredMiddleware', 
]

LOGIN_EXEMPT_URLS =( #<-- I am using allauth, so left some examples here)
    r'logout',
    r'register_user',
    r'accounts/google/login/',
    r'accounts/social/signup/',
    r'accounts/facebook/login/',
    
)

middleware.py (эти файлы входят в ваше основное приложение, по умолчанию «mysite»)

import re
from django.conf import settings
from django.shortcuts import redirect

EXEMPT_URLS = [re.compile(settings.LOGIN_URL.lstrip('/'))]
if hasattr(settings, 'LOGIN_EXEMPT_URLS'):
    EXEMPT_URLS += [re.compile(url) for url in settings.LOGIN_EXEMPT_URLS]

class LoginRequiredMiddleware:
    pass
    def __init__(self, get_response):
        self.get_response = get_response
        
    def __call__ (self, request):
        response = self.get_response(request)
        return response
    
    def process_view(self, request, view_func, view_args, view_kwargs):
        assert hasattr(request,'user')
        path = request.path_info.lstrip('/')
        print(path)
        
        if not request.user.is_authenticated:
            if not any(url.match(path) for url in EXEMPT_URLS):
                return redirect(settings.LOGIN_URL)
    

Я хотел предложить очень похожее решение, но вы сами его нашли. Но убедитесь, что он работает так, как вы ожидаете! process_view() метод устарел в промежуточном программном обеспечении, начиная с Django 1.10 (см. здесь).

Antwane 22.11.2022 13:53

Кроме того, в качестве альтернативы стандартному redirect() следует использовать помощник redirect_to_login(), чтобы упростить перенаправление на страницу входа. Это позволяет пройти «следующую» страницу, поэтому пользователь автоматически перенаправляется на первую страницу, которую он хотел открыть после успешного входа в систему.

Antwane 22.11.2022 13:53

Спасибо за комментарий! На самом деле я работал над перенаправлением несколько дней назад. В конечном итоге это сработало, ожидая AllAuth. Рассматривал возможность создания переопределяющего представления, чтобы разрешить перенаправление на предыдущую страницу. Как вы думаете, может ли помощник избежать необходимости создавать переопределяющее представление? (попробую сегодня вечером)

PhilM 22.11.2022 15:34

Только что протестировал код, он дает тот же результат, что и у меня сейчас (для перенаправления), однако он не работает, когда пользователь переходит со страницы входа на страницу регистрации и регистрирует учетную запись. В этом случае пользователь отправляется обратно в «LOGIN_REDIRECT_URL. Я пропустил быстрое решение?

PhilM 22.11.2022 17:37

Другие вопросы по теме