Почему URL запроса / HTTP_REFERRER в Django ошибочен с внешнего домена?
TL;DR
Получалась ошибка Django, потому что я неправильно перенаправлял аутентифицированных пользователей, делающих GET-запросы к конечной точке входа в систему (эта проблема устранена); однако я хотел бы понять, почему Request URL
/ HTTP_REFERRER
в сообщении об ошибке был внешний домен.
Фон
Я получаю несколько ошибок сервера Django в месяц в моем производственном веб-приложении, в которых sendgrid.net
указывается как Request URL
(а также HTTP_REFERRER
). Я понял, что некоторые из моих шаблонов транзакционных писем превращают ссылки в странные URL sendgrid для отслеживания кликов, поэтому я добавил clicktracking="off"
ко всем элементам якоря в моих шаблонах, чтобы избежать этого. Однако ошибки сохранились.
Текущая проблема
Сегодня я попытался перейти по адресу https://example.com/login/
, когда я уже вошел в систему, ожидая, что он перенаправит меня на страницу профиля пользователя, но вместо этого он выдал ошибку 500. Когда я посмотрел на сообщение об ошибке, которое было автоматически отправлено мне по электронной почте из моего приложения Django, оказалось, что Request URL
/ HTTP_REFERRER
- это не https://example.com/login/
, а скорее поддомен sendgrid.net
(см. ниже).
Ошибка возникала на моем представлении с названием CustomLoginView
:
Exception Type: NoReverseMatch at /login/
Exception Value: Reverse for 'member-detail' with no arguments not found. 1 pattern(s) tried: ['member/(?P<slug>[-a-zA-Z0-9_]+)/\\Z']
Raised during: home.views.CustomLoginView
Request information:
USER: Doe, John: john.doe@example.com
URL-адрес запроса Sendgrid
URL имеет следующую структуру: https://u<8-digit ID number>.ct.sendgrid.net/ls/click?upn=<extremely long string of characters>
.
views.py
Обратите внимание, что раньше в представлении не было redirect_authenticated_user = True
(что и вызывало ошибку). Я добавил эту строку, чтобы исправить ошибку.
from django.contrib.auth.views import LoginView
class CustomLoginView(LoginView):
"""
need custom login so I can set session timezone upon login
"""
redirect_authenticated_user = True # This is what I added to fix 500 server error
def form_valid(self, form):
"""Security check complete. Log the user in."""
auth_login(self.request, form.get_user())
# now set session timezone according to user's preference
tzname = self.request.user.tz_preference.key
self.request.session["django_timezone"] = tzname
# and activate it (after this view, middleware will activate it)
timezone.activate(zoneinfo.ZoneInfo(tzname))
return HttpResponseRedirect(self.get_success_url())
В чем причина?
Как мне кажется, здесь есть две проблемы:
- Мой
CustomLoginView
неправильно перенаправляет уже вошедших пользователей на их приборную панель при GET-запросе наCustomLoginView
. - Каким-то образом Sendgrid вовлечен в процесс, который я не могу понять. Как этот поддомен Sendgrid может перехватывать запрос к моему домену?
Я решил проблему номер один, установив redirect_authenticated_user = True
на моем CustomLoginView, но я не могу понять, почему Request URL
/ HTTP_REFERRER
были с этого поддомена Sendgrid.
То, что я пробовал
Я заметил, что у меня все еще есть три DNS-записи, связанные с Sendgrid, поэтому я удалил их, но ошибка все еще сохраняется.
Другая потенциально важная информация
Я использую NGINX и Gunicorn для обслуживания моего приложения