Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Manually Invoking email verification

We've been using django-allauth for quite some time now in production. We can enable account email verification which works great. But we now have a REST api that allows users to register through the API and the workflow doesn't go through django-allauth. Is it possible to manually invoke the django-allauth email verification feature or do we need to use a custom solution?

like image 869
Cliff F Avatar asked Feb 09 '23 12:02

Cliff F


2 Answers

I'll just post my answer here as I've been searching for adding email verification with Django Built-in Authentication (And using a Custom Auth Model), I used the method mentioned by Marcus, I'll just add all the other stuff around it for anyone who wants to do the same.

First: Install django-allauth as described here

Second: Add your email configurations in the settings.py file :

EMAIL_USE_TLS = True
EMAIL_HOST = 'smtp.gmail.com' #I used gmail in my case
EMAIL_HOST_USER = <Your Email>
EMAIL_HOST_PASSWORD = <Your Password>
EMAIL_PORT = 587
DEFAULT_FROM_EMAIL = <Default Sender name and email>

Third: Add configurations for verification and default login url, you'll find the documentation of all config parameters here, note that in my example I'm using a custom user model as mentioned, that's why I'm setting ACCOUNT_EMAIL_REQUIRED to True & ACCOUNT_USER_MODEL_USERNAME_FIELD and ACCOUNT_USERNAME_REQUIRED to False, also the LOGIN_URL,ACCOUNT_EMAIL_CONFIRMATION_AUTHENTICATED_REDIRECT_URL andLOGIN_REDIRECT_URL parameters are used after the user clicks on the confirmation link sent by email to him

ACCOUNT_EMAIL_VERIFICATION='mandatory'
ACCOUNT_CONFIRM_EMAIL_ON_GET=True
ACCOUNT_EMAIL_REQUIRED=True
ACCOUNT_USER_MODEL_USERNAME_FIELD = None
ACCOUNT_USERNAME_REQUIRED = False
ACCOUNT_AUTHENTICATION_METHOD = 'email'
LOGIN_URL='app:login_user'
LOGIN_REDIRECT_URL='app:login_user'
ACCOUNT_EMAIL_CONFIRMATION_AUTHENTICATED_REDIRECT_URL='app:login_user'

Fourth: After your signup form, save the user instance with is_active parameter set to False, then call the method:

from allauth.account.utils import *
send_email_confirmation(request, user, True)

Finally: Receive the signal after the user confirms his email, and set is_active to True

from allauth.account.signals import email_confirmed
from django.dispatch import receiver

# Signal sent to activate user upon confirmation
@receiver(email_confirmed)
def email_confirmed_(request, email_address, **kwargs):
    user = MyUser.objects.get(email=email_address.email)
    user.is_active = True
    user.save()

Finally, you would want to change the default site name from Django Admin as it will be included in the email sent.

like image 157
P. Naoum Avatar answered May 01 '23 23:05

P. Naoum


I had the same problem, and the solution I've found was to call the original send_email_confirmation method from allauth. I am using DRF3 for my API.

from allauth.account.utils import send_email_confirmation

...
def some_view(request):
    user = ...
    ...
    #using request._request to avoid TypeError on change made in DRF3 (from HTTPRequest to Request object)
    send_email_confirmation(request._request, user)
    ...

I hope this helps you.

like image 36
Marcus Beckenkamp Avatar answered May 01 '23 23:05

Marcus Beckenkamp