Search code examples
pythondjangodjango-rest-frameworkdjango-allauthdjango-rest-auth

django-rest-auth registration/verify-email/ not working


I just download demo from official django-rest-auth site and tried to use but some API endpoint not working.

I successfully signup (register) user with restful API, i get key in response:

 `{"key":"e96496ecb7fbe85d5ab60fe5d5f9a15b33a967fe"}`

and user exists (when i check in database) and i also get email with verification link, but when i try to verify its email with rest api:

 `curl -X POST http://127.0.0.1:9003/rest-auth/registration/verify-email/ -d "key=e96496ecb7fbe85d5ab60fe5d5f9a15b33a967fe"`

i am getting:

`{"detail":"Not found."}`

Where i am making mistake. This is just demo i didn't do anything just install, set sending email, host and run server.

Also when i click on link in email it opens page with confirm button and when i click on confirm i get:

`Using the URLconf defined in demo.urls, Django tried these URL patterns, in this order:
^$ [name='home']
^signup/$ [name='signup']
^email-verification/$ [name='email-verification']
^login/$ [name='login']
^logout/$ [name='logout']
^password-reset/$ [name='password-reset']
^password-reset/confirm/$ [name='password-reset-confirm']
^user-details/$ [name='user-details']
^password-change/$ [name='password-change']
^password-reset/confirm/(?P<uidb64>[0-9A-Za-z_\-]+)/(?P<token>[0-9A-Za-z]{1,13}-[0-9A-Za-z]{1,20})/$ [name='password_reset_confirm']
^rest-auth/
^rest-auth/registration/
^account/
^admin/
^accounts/profile/$ [name='profile-redirect']
^docs/$ [name='api_docs']
The current path, accounts/login/, didn't match any of these.`

Why this also doesn't work? This is demo where i am making mistake?

Please help!

UPDATE1:

Here is settings.py file:

`"""
Django settings for demo project.

For more information on this file, see
https://docs.djangoproject.com/en/1.7/topics/settings/

For the full list of settings and their values, see
https://docs.djangoproject.com/en/1.7/ref/settings/
"""

# Build paths inside the project like this: os.path.join(BASE_DIR, ...)
import os

BASE_DIR = os.path.dirname(os.path.dirname(__file__))

# Quick-start development settings - unsuitable for production
# See https://docs.djangoproject.com/en/1.7/howto/deployment/checklist/

# SECURITY WARNING: keep the secret key used in production secret!
SECRET_KEY = 'ma3c@7uu!%e0=tynp+i6+q%$)9v@$t(eulqurym_b=48z82&5n'

# SECURITY WARNING: don't run with debug turned on in production!
DEBUG = True

ALLOWED_HOSTS = ['127.0.0.1']

# Application definition

INSTALLED_APPS = (
    'django.contrib.admin',
    'django.contrib.auth',
    'django.contrib.contenttypes',
    'django.contrib.sessions',
    # 'django.contrib.messages',
    'django.contrib.staticfiles',
    'django.contrib.sites',

    'rest_framework',
    'rest_framework.authtoken',
    'rest_auth',

    'allauth',
    'allauth.account',
    'rest_auth.registration',
    'allauth.socialaccount',
    'allauth.socialaccount.providers.facebook',
    'rest_framework_swagger',
)

MIDDLEWARE_CLASSES = (
    'django.contrib.sessions.middleware.SessionMiddleware',
    'django.middleware.common.CommonMiddleware',
    'django.middleware.csrf.CsrfViewMiddleware',
    'django.contrib.auth.middleware.AuthenticationMiddleware',
    'django.contrib.auth.middleware.SessionAuthenticationMiddleware',
    'django.contrib.messages.middleware.MessageMiddleware',
    'django.middleware.clickjacking.XFrameOptionsMiddleware',
)

ROOT_URLCONF = 'demo.urls'

WSGI_APPLICATION = 'demo.wsgi.application'

# Database
# https://docs.djangoproject.com/en/1.7/ref/settings/#databases

DATABASES = {
    'default': {
        'ENGINE': 'django.db.backends.sqlite3',
        'NAME': os.path.join(BASE_DIR, 'db.sqlite3'),
    }
}

# Internationalization
# https://docs.djangoproject.com/en/1.7/topics/i18n/

LANGUAGE_CODE = 'en-us'

TIME_ZONE = 'UTC'

USE_I18N = True

USE_L10N = True

USE_TZ = True

# Static files (CSS, JavaScript, Images)
# https://docs.djangoproject.com/en/1.7/howto/static-files/

STATIC_URL = '/static/'

# TEMPLATE_DIRS = [os.path.join(BASE_DIR, 'templates')]

TEMPLATES = [
    {
        'BACKEND': 'django.template.backends.django.DjangoTemplates',
        'DIRS': [os.path.join(BASE_DIR, 'templates'), ],
        'APP_DIRS': True,
        'OPTIONS': {
            'context_processors': [
                'django.template.context_processors.debug',
                'django.template.context_processors.request',
                'django.contrib.auth.context_processors.auth',
                'django.contrib.messages.context_processors.messages',
            ],
        },
    },
]

REST_SESSION_LOGIN = True
#EMAIL_BACKEND = 'django.core.mail.backends.console.EmailBackend'
SITE_ID = 1
ACCOUNT_EMAIL_REQUIRED = True
ACCOUNT_AUTHENTICATION_METHOD = 'email'
ACCOUNT_EMAIL_VERIFICATION = 'optional'

REST_FRAMEWORK = {
    'DEFAULT_AUTHENTICATION_CLASSES': (
        'rest_framework.authentication.SessionAuthentication',
        'rest_framework.authentication.TokenAuthentication',
    )
}

SWAGGER_SETTINGS = {
    'LOGIN_URL': 'login',
    'LOGOUT_URL': 'logout',
}

DEFAULT_FROM_EMAIL = '[email protected]'
EMAIL_HOST = 'smtp.mail.xxxx.com'
EMAIL_PORT = 587
EMAIL_HOST_USER = '[email protected]'
EMAIL_HOST_PASSWORD = 'xxxxx'
EMAIL_USE_TLS = True`

And Here is urls.py

from django.conf.urls import include, url
from django.contrib import admin
from django.views.generic import TemplateView, RedirectView

from rest_framework_swagger.views import get_swagger_view

urlpatterns = [
    url(r'^$', TemplateView.as_view(template_name="home.html"), name='home'),
    url(r'^signup/$', TemplateView.as_view(template_name="signup.html"),
        name='signup'),
    url(r'^email-verification/$',
        TemplateView.as_view(template_name="email_verification.html"),
        name='email-verification'),
    url(r'^login/$', TemplateView.as_view(template_name="login.html"),
        name='login'),
    url(r'^logout/$', TemplateView.as_view(template_name="logout.html"),
        name='logout'),
    url(r'^password-reset/$',
        TemplateView.as_view(template_name="password_reset.html"),
        name='password-reset'),
    url(r'^password-reset/confirm/$',
        TemplateView.as_view(template_name="password_reset_confirm.html"),
        name='password-reset-confirm'),

    url(r'^user-details/$',
        TemplateView.as_view(template_name="user_details.html"),
        name='user-details'),
    url(r'^password-change/$',
        TemplateView.as_view(template_name="password_change.html"),
        name='password-change'),


    # this url is used to generate email content
    url(r'^password-reset/confirm/(?P<uidb64>[0-9A-Za-z_\-]+)/(?P<token>[0-9A-Za-z]{1,13}-[0-9A-Za-z]{1,20})/$',
        TemplateView.as_view(template_name="password_reset_confirm.html"),
        name='password_reset_confirm'),

    url(r'^rest-auth/', include('rest_auth.urls')),
    url(r'^rest-auth/registration/', include('rest_auth.registration.urls')),
    url(r'^account/', include('allauth.urls')),
    url(r'^admin/', include(admin.site.urls)),
    url(r'^accounts/profile/$', RedirectView.as_view(url='/', permanent=True), name='profile-redirect'),
    url(r'^docs/$', get_swagger_view(title='API Docs'), name='api_docs')
]

UPDATE2:

I think i have found something. In confirmation email i got link which looks like:

 http://127.0.0.1:9003/account/confirm-email/MQ:1d2Go5:SHdLaJz9Pa1HluHw_Djr26jm3Q8/

Now if I use MQ:1d2Go5:SHdLaJz9Pa1HluHw_Djr26jm3Q8 as key in rest api i got success response. But now I don't know what is a key that i get from curl response and what is key that i get from confirmation email link:

key from curl response: e96496ecb7fbe85d5ab60fe5d5f9a15b33a967fe (this value is placed in database in table authtoken_token

key from confirmation email link: MQ:1d2Go5:SHdLaJz9Pa1HluHw_Djr26jm3Q8

Please explain me difference


Solution

  • I have discovered what is solution. It was not problem in settings it was problem in my understanding what key goes where.

    The key that you got from json api in response {"key":"e96496ecb7fbe85d5ab60fe5d5f9a15b33a967fe"} is key that you need to use in header for each api call that needs authentication. But key that you got in confirmation email "MQ:1d2Go5:SHdLaJz9Pa1HluHw_Djr26jm3Q8" which is part of confirmation link is used only for verification. Instead you click on confirmation link in email you can take that part (key) and verify your account with restful api. That's all. There are two different keys. One which is authentication key is important and you always need to keep it and send it with requests so server knows that you are logged in and second key is just for verification of account and you use it only once when you register new account and need to verify it. You can verify it with clicking on link in confirmation email or to take key from that link and manually send it with verify api call to verify you new account.