Sendgrid-python: HTTP Error 403 when sending account signup email in Django project

Created on 8 May 2020  路  12Comments  路  Source: sendgrid/sendgrid-python

Issue Summary

I'm using the django-sendgrid-v5 package in conjunction with django-allauth to send the confirmation emails when a new user creates an account. When the user submits the form at /accounts/signup/ the account is created in Django, but the email confirmation fails with a 403 error.

I haven't made any changes to the default django-allauth settings. I'm posting here because it seems possible that the issue may be related to the underlying python-sendgrid configuration.

Exception/Log

Traceback (most recent call last):
  File "/usr/local/lib/python3.7/site-packages/python_http_client/client.py", line 174, in _make_request
    return opener.open(request, timeout=timeout)
  File "/usr/local/lib/python3.7/urllib/request.py", line 531, in open
    response = meth(req, response)
  File "/usr/local/lib/python3.7/urllib/request.py", line 641, in http_response
    'http', request, response, code, msg, hdrs)
  File "/usr/local/lib/python3.7/urllib/request.py", line 569, in error
    return self._call_chain(*args)
  File "/usr/local/lib/python3.7/urllib/request.py", line 503, in _call_chain
    result = func(*args)
  File "/usr/local/lib/python3.7/urllib/request.py", line 649, in http_error_default
    raise HTTPError(req.full_url, code, msg, hdrs, fp)

During handling of the above exception (HTTP Error 403: Forbidden), another exception occurred:
  File "/usr/local/lib/python3.7/site-packages/django/core/handlers/exception.py", line 34, in inner
    response = get_response(request)
  File "/usr/local/lib/python3.7/site-packages/django/core/handlers/base.py", line 115, in _get_response
    response = self.process_exception_by_middleware(e, request)
  File "/usr/local/lib/python3.7/site-packages/django/core/handlers/base.py", line 113, in _get_response
    response = wrapped_callback(request, *callback_args, **callback_kwargs)
  File "/usr/local/lib/python3.7/site-packages/django/views/generic/base.py", line 71, in view
    return self.dispatch(request, *args, **kwargs)
  File "/usr/local/lib/python3.7/site-packages/django/utils/decorators.py", line 43, in _wrapper
    return bound_method(*args, **kwargs)
  File "/usr/local/lib/python3.7/site-packages/django/views/decorators/debug.py", line 76, in sensitive_post_parameters_wrapper
    return view(request, *args, **kwargs)
  File "/usr/local/lib/python3.7/site-packages/allauth/account/views.py", line 215, in dispatch
    return super(SignupView, self).dispatch(request, *args, **kwargs)
  File "/usr/local/lib/python3.7/site-packages/allauth/account/views.py", line 81, in dispatch
    **kwargs)
  File "/usr/local/lib/python3.7/site-packages/allauth/account/views.py", line 193, in dispatch
    **kwargs)
  File "/usr/local/lib/python3.7/site-packages/django/views/generic/base.py", line 97, in dispatch
    return handler(request, *args, **kwargs)
  File "/usr/local/lib/python3.7/site-packages/allauth/account/views.py", line 104, in post
    response = self.form_valid(form)
  File "/usr/local/lib/python3.7/site-packages/allauth/account/views.py", line 236, in form_valid
    self.get_success_url())
  File "/usr/local/lib/python3.7/site-packages/allauth/account/utils.py", line 192, in complete_signup
    signal_kwargs=signal_kwargs)
  File "/usr/local/lib/python3.7/site-packages/allauth/account/utils.py", line 152, in perform_login
    send_email_confirmation(request, user, signup=signup)
  File "/usr/local/lib/python3.7/site-packages/allauth/account/utils.py", line 323, in send_email_confirmation
    signup=signup)
  File "/usr/local/lib/python3.7/site-packages/allauth/account/models.py", line 58, in send_confirmation
    confirmation.send(request, signup=signup)
  File "/usr/local/lib/python3.7/site-packages/allauth/account/models.py", line 163, in send
    get_adapter(request).send_confirmation_mail(request, self, signup)
  File "/usr/local/lib/python3.7/site-packages/allauth/account/adapter.py", line 450, in send_confirmation_mail
    ctx)
  File "/usr/local/lib/python3.7/site-packages/allauth/account/adapter.py", line 137, in send_mail
    msg.send()
  File "/usr/local/lib/python3.7/site-packages/django/core/mail/message.py", line 276, in send
    return self.get_connection(fail_silently).send_messages([self])
  File "/usr/local/lib/python3.7/site-packages/sendgrid_backend/mail.py", line 122, in send_messages
    resp = self.sg.client.mail.send.post(request_body=data)
  File "/usr/local/lib/python3.7/site-packages/python_http_client/client.py", line 262, in http_request
    self._make_request(opener, request, timeout=timeout)
  File "/usr/local/lib/python3.7/site-packages/python_http_client/client.py", line 178, in _make_request
    raise exc

Exception Type: ForbiddenError at /accounts/signup/
Exception Value: HTTP Error 403: Forbidden

Here are the relevant settings:

# settings.py
EMAIL_BACKEND = 'sendgrid_backend.SendgridBackend'
FROM_EMAIL = '[email protected]'
SENDGRID_API_KEY = os.environ.get("SENDGRID_API_KEY")
SENDGRID_SANDBOX_MODE_IN_DEBUG=False
SENDGRID_ECHO_TO_STDOUT=True

Technical details:

  • Django 3.0.5
  • Python 3.7.6
  • I'm running Django in debug mode on my local machine in a Docker container. I'm using the SendGrid Web API and not SMTP.
  • My API key is set for "Full Access."
  • I'm using SendGrid domain verification which it says is verified.
  • Sending email to the console by setting EMAIL_BACKEND = 'django.core.mail.backends.console.EmailBackend' works fine. I see the confirmation emails there.
  • The test mail from the python console as given in the Sending Emails with Django using SendGrid in 3 easy steps article works just as shown.
support

Most helpful comment

That looks promising.

All 12 comments

I have some problem. I try send use django or native python still 403 forbidden.

I've submitted a ticket to SendGrid support and am waiting for their response.

Same problem here, API Key with full access and getting 403 forbidden.

20200515_044848
I resolve this by authorizing sender domain

@irfanpule, thanks for the suggestion. That's not the issue on my case because my domain is verified.

Interestingly, other emails from my system are flowing through SendGrid without any difficulty. For some reason, an attempt to send email from this form is triggering that 403.

Hello @timwilson,

Thanks for submitting a GitHub issue! We are very sorry that you are running into this problem. In order to better serve you, as this does not present itself as a library specific issue, we would like to ask that you reach out to our support team at https://support.sendgrid.com.

Thank you!

SendGrid DX Team

Hey @timwilson ,

Have you figured out the problem? Facing a same issue.

@s-agawane Solved my problem by setting the email sender as the same one in sendgrid settings "Single Sender Verification", otherwise a Forbidden 403 will happen, even though the API key has full access. You'll only be able to send emails using the API key from this verified email or domain (using Domain Authentication).

@s-agawane and @Argonalyst,

I have Domain Authentication enabled on my SendGrid account (as well as Link Branding). I'm new to this, but my understanding from reading the documentation is that any address from my domain would be able to send email through SendGrid once my domain is authenticated. In fact, I've successfully sent email through SendGrid from my site on other pages triggered by certain changes in my database. It's just the account signup screen and my contact form that are failing. The other emails are coming from an account at my domain that isn't listed anywhere in my SendGrid settings. (And further, emails from those two pages work perfectly when I send them to the console backend or through MailHog which I configured to help me troubleshoot this problem.

Even more troubling, however, is the complete lack of response from SendGrid to this problem. I'm currently using a free account as I evaluate their service and test my site which I hope will go live by the end of the month. I submitted a ticket about this issue on May 13th and haven't heard a single word from them. I may not be a paying customer yet, but I would think they'd have an interest in helping a potential paying customer get things working. Even a "we don't think this is a problem with our system" message would be helpful at this point.

I'm going to give them until tomorrow (that would be 10 days since I created the ticket). If I don't hear from them I'm going to switch to a different provider. This is mission critical for my site.

I had this issue, and found the solution (after about 3h of banging my head on the wall).

As posted here: https://github.com/sklarsa/django-sendgrid-v5/issues/65#issuecomment-633773759

I think I solved it.

I went into https://app.sendgrid.com/settings/sender_auth/domains then on my verified domain I clicked on Use as default domain, after that it works like a charm.

Before that, the from email had to be @emXXXX.mydomain.com otherwise I'd get the 403 error.

This is a very easy solution but I feel that Sendgrid should either:

1 - When you have only 1 domain validated, automatically set it as the default one
2 - Clearly document that you either need to set the domain as default, or you'll need to send emails from the random subdomain you set up.

That looks promising.

This appears to fail because by default django is sending password reset emails etc from [email protected] which will not match your verified sender in sendgrid. In django settings.py you need to add DEFAULT_FROM_EMAIL = '[email protected]'

Was this page helpful?
0 / 5 - 0 ratings

Related issues

thinkingserious picture thinkingserious  路  3Comments

hanhaa picture hanhaa  路  4Comments

lipis picture lipis  路  3Comments

andriisoldatenko picture andriisoldatenko  路  4Comments

sohamnavadiya picture sohamnavadiya  路  4Comments