Reputation: 2837
I'm trying to change where the user is redirected to after they've confirmed their email address by clicking the link in the confirmation email.
I'm using Django 2.0.10 with allauth, rest-auth and rest-framework. For the email verification, I'm using the default allauth view.
In my settings.py I have set the following:
INSTALLED_APPS = [
'api',
'dynamic_rest',
'django.contrib.admin',
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.messages',
'django.contrib.staticfiles',
'rest_framework',
'rest_framework.authtoken',
'django.contrib.sites',
'allauth.account',
'allauth.socialaccount',
'rest_auth.registration',
'users',
'lists',
'rest_auth',
'allauth', # needs to be at the end so custom templates are found first
]
EMAIL_CONFIRMATION_AUTHENTICATED_REDIRECT_URL = '/'
print('EMAIL_CONFIRMATION_AUTHENTICATED_REDIRECT_URL')
print(EMAIL_CONFIRMATION_AUTHENTICATED_REDIRECT_URL)
urls.py
from allauth.account.views import confirm_email
urlpatterns = [
re_path(r'^rest-auth/registration/account-confirm-email/(?P<key>[-:\w]+)/$', confirm_email,
name='account_confirm_email'),
...
]
My setting '/' is indeed printed in the console, so I think it is being picked up by the app. But when I follow the link in the email to the page (http://localhost:8000/api/v1/rest-auth/registration/account-confirm-email/MTQ:1gpYgM:_KpNYl-nd2iiG0qLIRRdVrmF8SM/) and then click the 'confirm' button, I am redirected to the default page /accounts/profile instead of the home page as specified by EMAIL_CONFIRMATION_AUTHENTICATED_REDIRECT_URL.
This setting also doesn't seem to have any effect:
ACCOUNT_LOGIN_ON_EMAIL_CONFIRMATION = False
I want to disable it because the login doesn't work - the token is invalid. Perhaps allauth logs in differently to rest-auth? I don't mind if the user has to log in after verifying their email address, but the current behaviour that the user appears to be logged in, but isn't, is not OK.
What am I doing wrong, how can I customise where the user is redirected after confirming their email address? Many thanks for any help!
Upvotes: 3
Views: 1700
Reputation: 2837
After a lot of fiddling about, I think the allauth settings don't work how I expected from their names and maybe don't work as intended. ACCOUNT_EMAIL_CONFIRMATION_AUTHENTICATED_REDIRECT_URL does not mean "redirect after the user logged in". The code tests on user.is_authenticated (site-packages/allauth/account/adapter.py) which in this context seems to mean "was the confirmation link valid?".
ACCOUNT_LOGIN_ON_EMAIL_CONFIRMATION doesn't seem to work at all with token authentication, and anyway is known not to work if the session has changed. So I think it must be set to False.
ACCOUNT_LOGIN_ON_EMAIL_CONFIRMATION = False seems to be honoured sometimes but not always and I haven't found out why...
Looking at how the email_confirm.html template is built, I think that success will always redirect you to ACCOUNT_EMAIL_CONFIRMATION_AUTHENTICATED_REDIRECT_URL and failure will keep you on the page with a non-working link to request a new confirmation email.
I can't find when ACCOUNT_EMAIL_CONFIRMATION_ANONYMOUS_REDIRECT_URL would be used but have set it to the home page.
I may have misunderstood this, but I have finally got a sort-of-working setup. It's very cludgy, there must be a better way to do this but right now I'll take anything that lets me move on. I have ended up using several allauth templates for account management because I can't get this working with rest-auth.
There is still an issue with failed links: mostly I see the template page with its useful message, but sometimes it just shows the home page. But at least that is not the main flow and not a disaster for the user.
settings.py: note the template DIRS entry for allauth, otherwise my custom template is not used
TEMPLATES = [
{
...
'DIRS': [os.path.join(BASE_DIR, 'templates'),
os.path.join(BASE_DIR, 'assets'),
os.path.join(BASE_DIR, 'templates', 'allauth')],
...
]
ACCOUNT_LOGIN_ON_EMAIL_CONFIRMATION = False
ACCOUNT_EMAIL_CONFIRMATION_ANONYMOUS_REDIRECT_URL = '/'
ACCOUNT_EMAIL_CONFIRMATION_AUTHENTICATED_REDIRECT_URL = '/verified'
'verified' is a route in my front end that displays a confirmation message and a link to login.
urls.py
from django.views.generic import TemplateView
urlpatterns = [
...
re_path(r'^rest-auth/registration/account-confirm-email/(?P<key>[-:\w]+)/$', confirm_email,
name='account_confirm_email'),
]
templates/account/email_confirm.html, modified to give a working link on failure
{% extends "account/base.html" %}
{% load i18n %}
{% load account %}
{% block head_title %}{% trans "Confirm E-mail Address" %}{% endblock %}
{% block content %}
<h1>{% trans "Confirm E-mail Address" %}</h1>
{% if confirmation %}
{% user_display confirmation.email_address.user as user_display %}
<p>{% blocktrans with confirmation.email_address.email as email %}Please confirm that <a href="mailto:{{ email }}">{{ email }}</a> is an e-mail address for user {{ user_display }}.{% endblocktrans %}</p>
<form method="post" action="{% url 'account_confirm_email' confirmation.key %}">
{% csrf_token %}
<button type="submit">{% trans 'Confirm' %}</button>
</form>
{% else %}
{% url 'account_email' as email_url %}
<p>{% blocktrans %}The email confirmation link expired or is invalid. Please <a href="/login/">login</a> and request a new confirmation email from your user account.{% endblocktrans %}</p>
{% endif %}
{% endblock %}
Upvotes: 4