django-rest-auth icon indicating copy to clipboard operation
django-rest-auth copied to clipboard

account-confirm-email raises ImproperlyConfigured

Open jokimies opened this issue 8 years ago • 14 comments

Used relevant pieces:

django-allauth==0.28.0
django-rest-auth==0.8.2
Django==1.10.3
djangorestframework==3.5.3

Created a user with POST request to /rest-auth/registration/ User was created fine, an verification email was send, with a link to verify the email address. However, clinking the link results in error:

Internal Server Error: /rest-auth/registration/account-confirm-email/Ng:1cGlUl:EvPY0Yyu6YHLZEWEtIp/
....
ImproperlyConfigured: TemplateResponseMixin requires either a definition of 'template_name'
 or an implementation of 'get_template_names()'

I believe the error is in rest_auth.registration.urls:

url(r'^account-confirm-email/(?P<key>[-:\w]+)/$', TemplateView.as_view(),
name='account_confirm_email'),

Django docs are saying (https://docs.djangoproject.com/en/1.10/ref/class-based-views/base/#templateview) that TemplateView inherits from TemplateResponseMixin, and docs for that (https://docs.djangoproject.com/en/1.10/ref/class-based-views/mixins-simple/#django.views.generic.base.TemplateResponseMixin) are telling that 'Not defining a template_name will raise a django.core.exceptions.ImproperlyConfigured exception.' That would suggest that TemplateView.as_view() need template_name argument.

In my urls.py I have

url(r'^rest-auth/', include('rest_auth.urls')),
url(r'^rest-auth/registration/', include('rest_auth.registration.urls')),

i.e I'm not trying to define any own views, just using the provided ones.

If I go and change rest_auth.registration.urls to contain

url(r'^account-confirm-email/(?P<key>[-:\w]+)/$', TemplateView.as_view(template_name='empty.html'),
name='account_confirm_email')

and making sure that django finds that empty.html (which is totally blank), the 'ImproperlyConfigured' exception disappears (but don't known what the template actually should contain)

jokimies avatar Dec 14 '16 14:12 jokimies

Appears this is a feature and reported a few times earlier eg. https://github.com/Tivix/django-rest-auth/issues/15 Maybe a mention in documentation that one should overwrite the view (couldn't see any), maybe same info to documentation as in https://github.com/Tivix/django-rest-auth/issues/15#issuecomment-59034727 ?

jokimies avatar Dec 14 '16 16:12 jokimies

I'm working on the same issue. The user is created and the email is sent, but clicking the link gives me the improperly configured error as well. What i'm more interested in getting is the api to verify as well via the 'verify-email/' endpoint. posting the key to the endpoint should have the same effect as clicking the link, correct?

[edit] Got the API working, but it still leaves a few questions...

okc0mputer avatar Dec 22 '16 04:12 okc0mputer

Hey there. I'm struggling with all of this as well. And I must say that documentation falls a bit short just before the end of the tutorial...

But I managed to get the right confirmation email view, without any special trick, but rather by noticing two issues, which, taken together, can get you lost for a long time.

First, the regex found in the FAQ (?P<key>[-:\w]+)/$ doesn't work. I personally used this (?P<key>\w+)/$ for a while, found on Stackoverflow probably, and never realised this couldn't be enough. Anyway, both fail, as far as I can tel. This is problematic because the system creates confirmation keys that aren't understood by urls routes.

I personally use (?P<key>[\s\d\w().+-_',:&]+)/$.

Second, if you are like me and have a personal proud to keep things neatly organised, you end up having your urls like that:

from allauth.account.views import confirm_email as allauthemailconfirmation

(...)
    url(r'^rest-auth/', include('rest_auth.urls')),
    url(r'^rest-auth/registration/', include('rest_auth.registration.urls')),
    url(r'^rest-auth/registration/account-confirm-email/(?P<key>{0})/$'.format(regex.full_string_regex),
        allauthemailconfirmation, name="account_confirm_email"),

But the thing is, the url you request is being caught up by the second url line url(r'^rest-auth/registration/', include('rest_auth.registration.urls')), and fails, before evaluating the last one, which is the one we wants url(r'^rest-auth/registration/account-confirm-email/...! And the failure is precisely the one that triggered this GitHub issue thread.

Hence, you should swap the two url routes, and you're good to go. As a general rule, specific url routes like that should come before more general ones.

My two cents. Hope this helps.

onekiloparsec avatar Mar 19 '17 08:03 onekiloparsec

@onekiloparsec when I try to use your solution I get an error
name 'regex' is not defined How do I import the 'regex' module that you are using?

Shelagh-Lewins avatar Jan 31 '19 17:01 Shelagh-Lewins

The regex module is just a python file I wrote myself, and where I store all my regexes. The only important and relevant part, for the example above, is, in the regex.py file:

full_string_regex = "(?P<key>[\s\d\w().+-_',:&]+)/$"

onekiloparsec avatar Jan 31 '19 17:01 onekiloparsec

Ah, thanks! I got it working with this:

url(r"^rest-auth/registration/account-confirm-email/(?P<key>[\s\d\w().+-_',:&]+)/$", confirm_email,
        name="account_confirm_email"),

Shelagh-Lewins avatar Jan 31 '19 18:01 Shelagh-Lewins

Would you be able to say how to use your regex with the newer re_path syntax? This fails with a syntax error: re_path(r'^rest-auth/registration/account-confirm-email/(?P<key>[\s\d\w().+-_',:&]+)/$', confirm_email, name='account_confirm_email'),

Shelagh-Lewins avatar Jan 31 '19 18:01 Shelagh-Lewins

hey i too m also getting same error :from django.urls import include, path from allauth.account.views import confirm_email

as allauthemailconfirmation

from rest_framework_jwt.views import obtain_jwt_token urlpatterns = [ path('rest-auth/', include('rest_auth.urls')), path('rest-auth/registration/', include('rest_auth.registration.urls')), path("rest-auth/registration/account-confirm-email/",include('rest_auth.registration.urls') , name="confirm_email"), path('api-token-auth/',obtain_jwt_token), let me know how to ressolve this i know that the error is because of these following only

and the error m getting is : "TemplateResponseMixin requires either a definition of " django.core.exceptions.ImproperlyConfigured: TemplateResponseMixin requires either a definition of 'template_name' or an implementation of 'get_template_names()' [01/Apr/2019 06:25:51] "GET /api/v1/rest-auth/registration/account-confirm-email/account-confirm-email/Mjk:1hAqO4:tU562SfhiYl8bf3qgG5uz9THD9E/ HTTP/1.1" 500 93136

saptami2016 avatar Apr 01 '19 06:04 saptami2016

As for me I have a separate app to handle this authentication so when I put:

from django.contrib import admin
from django.urls import path, include, re_path

from rest_framework.routers import DefaultRouter
from rest_framework.schemas import get_schema_view
from rest_auth.registration.views import VerifyEmailView

schema_view = get_schema_view(title='API')

urlpatterns = [
    path('', include(router.urls)),
    path('admin/', admin.site.urls),
    path('api/v1/', include('api.urls')),

    re_path(r'registration/account-confirm-email/', VerifyEmailView.as_view(),
            name='account_email_verification_sent'),
    re_path(r'registration/account-confirm-email/(?P<key>[-:\w]+)/', VerifyEmailView.as_view(),
            name='account_confirm_email')
]

in my project.project.urls module it works, but if I move those lines to project.users.urls I get the:

Reverse for 'account_confirm_email' not found. 'account_confirm_email' is not a valid view function or pattern name.

error. I find it dirty to have the urls handling the email confimation outside my users app, any idea how I can make django look for account_confirm_email in my users app instead of my root app url module? One solution could be to add in project.project.urls:

path('', include('project.users.urls')),

But that's also a dirty solution =/

godardt avatar May 26 '19 13:05 godardt

I managed to solve the issue, in the file: /venv/lib/python3.6/site-packages/rest_auth/registration/urls.py add

from allauth.account.views import confirm_email #url(r'^account-confirm-email/(?P<key>[-:\w]+)/$', TemplateView.as_view(template_name='empty.html'), name='account_confirm_email'), url(r"^account-confirm-email/(?P<key>[\s\d\w().+-_',:&]+)/$", confirm_email, name="account_confirm_email"), and you don't need to add the path of auth/registration/confirm-email to project urls, you just need to add path('rest-auth/registration/', include('rest_auth.registration.urls')), another issue you might face is redirect to accounts/login, you can redirect to login page using nginx redirect.

scientronic92 avatar Aug 31 '19 18:08 scientronic92

Hey there. I'm struggling with all of this as well. And I must say that documentation falls a bit short just before the end of the tutorial...

But I managed to get the right confirmation email view, without any special trick, but rather by noticing two issues, which, taken together, can get you lost for a long time.

First, the regex found in the FAQ (?P<key>[-:\w]+)/$ doesn't work. I personally used this (?P<key>\w+)/$ for a while, found on Stackoverflow probably, and never realised this couldn't be enough. Anyway, both fail, as far as I can tel. This is problematic because the system creates confirmation keys that aren't understood by urls routes.

I personally use (?P<key>[\s\d\w().+-_',:&]+)/$.

Second, if you are like me and have a personal proud to keep things neatly organised, you end up having your urls like that:

from allauth.account.views import confirm_email as allauthemailconfirmation

(...)
    url(r'^rest-auth/', include('rest_auth.urls')),
    url(r'^rest-auth/registration/', include('rest_auth.registration.urls')),
    url(r'^rest-auth/registration/account-confirm-email/(?P<key>{0})/$'.format(regex.full_string_regex),
        allauthemailconfirmation, name="account_confirm_email"),

But the thing is, the url you request is being caught up by the second url line url(r'^rest-auth/registration/', include('rest_auth.registration.urls')), and fails, before evaluating the last one, which is the one we wants url(r'^rest-auth/registration/account-confirm-email/...! And the failure is precisely the one that triggered this GitHub issue thread.

Hence, you should swap the two url routes, and you're good to go. As a general rule, specific url routes like that should come before more general ones.

My two cents. Hope this helps.

Django3 Python 3.7 Neither import regex nor from regex import regex works How do solve this issue?

elcolie avatar Jan 29 '20 16:01 elcolie

Django3 Python 3.7 Neither import regex nor from regex import regex works How do solve this issue?

See https://github.com/Tivix/django-rest-auth/issues/290#issuecomment-459437238

onekiloparsec avatar Jan 29 '20 16:01 onekiloparsec

@onekiloparsec Thank you for hinting. I got the answer https://github.com/Tivix/django-rest-auth/issues/290#issuecomment-459447151

Ah, thanks! I got it working with this:

url(r"^rest-auth/registration/account-confirm-email/(?P<key>[\s\d\w().+-_',:&]+)/$", confirm_email,
        name="account_confirm_email"),

elcolie avatar Jan 29 '20 16:01 elcolie

Hello,

Just refer this Demo. It working for me.

https://github.com/MuhammadAnas47/django-rest-auth/tree/master/demo

MuhammadAnas47 avatar May 11 '24 12:05 MuhammadAnas47