Why is the request URL / HTTP_REFERRER in Django error from an external domain?
TL;DR
Was getting a Django error because I wasn't properly redirecting authenticated users making GET requests to my login endpoint (fixed this problem); however, I'd like to understand why the Request URL
/ HTTP_REFERRER
in the error message was an external domain.
Background
I've been getting a few Django server errors per month in my production web app that list sendgrid.net
as the Request URL
(as well as the HTTP_REFERRER
). I realized that some of my transactional email templates were turning links into strange sendgrid URLs for clicktracking, so I added clicktracking="off"
to all the anchor elements in my templates to avoid this. However, the errors have persisted.
Current Problem
Today I tried navigating to https://example.com/login/
when I was already logged in, expecting it to redirect me to my user profile page but instead it triggered a 500 error. When I looked at the error readout that was automatically emailed to me from my Django app, the Request URL
/ HTTP_REFERRER
was not https://example.com/login/
but rather a subdomain of sendgrid.net
(see below).
The error was being triggered on my view called 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
The Sendgrid Request URL
The URL is structured like this: https://u<8-digit ID number>.ct.sendgrid.net/ls/click?upn=<extremely long string of characters>
.
views.py
Note that the view did not have redirect_authenticated_user = True
before (which was causing the error). I added that line to fix the error.
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())
What is the cause?
The way I see it, there are two problems here:
- My
CustomLoginView
is not properly redirecting already-logged-in users to their dashboard when a GET request is made toCustomLoginView
. - Somehow, Sendgrid is involved in a way I cannot begin to understand. How can this subdomain of Sendgrid be hijacking a request to my domain?
I fixed problem number one by setting redirect_authenticated_user = True
on my CustomLoginView, but I can't figure out why the Request URL
/ HTTP_REFERRER
were from this Sendgrid subdomain.
Things I tried
I noticed I still had three DNS records having to do with Sendgrid, so I deleted those, but the error is still persisting.
Other potentially relevant info
I'm using NGINX and Gunicorn to serve my application