How to fix dj-rest-auth sending invalid password rest links - django

In my Django Rest Framework, the users request to reset the password and when the email is received everytime the link is clicked it shows a message Password reset unsuccessful The password reset link was invalid, possibly because it has already been used. Please request a new password reset.
here is what I have tried API urls.py
app_name = 'api'
router = routers.DefaultRouter()
router.register(r'users', UserViewSet, basename='user')
urlpatterns = [
path('', include(router.urls)),
path('dj-rest-auth/', include('dj_rest_auth.urls')),
path('dj-rest-auth/registration/', include('dj_rest_auth.registration.urls')),
path('token/', TokenObtainPairView.as_view(), name='token_obtain_pair'),
path('token/refresh/', TokenRefreshView.as_view(), name='token_refresh'),
# path('password_reset/',PasswordResetView.as_view(), name='password_reset'),
# path('password_reset_confirm/<uidb64>/<token>/', PasswordResetConfirmView.as_view(), name='password_reset_confirm'),
]
here is the users app urls.py if required:
app_name = 'users'
urlpatterns = [
path('password-reset/', auth_views.PasswordResetView.as_view(template_name='users/password_reset.html', success_url=reverse_lazy('users:password_reset_done')), name='password_reset'),
path('password-reset/done/', auth_views.PasswordResetDoneView.as_view(template_name='users/password_reset_done.html'),name='password_reset_done'),
path('password-reset-confirm/<uidb64>/<token>/',auth_views.PasswordResetConfirmView.as_view(template_name='users/password_reset_confirm.html',success_url=reverse_lazy('users:password_reset_done'),post_reset_login=True),name='password_reset_confirm',),
path('password-reset-complete/', auth_views.PasswordResetCompleteView.as_view(template_name='users/password_reset_complete.html'),name='password_reset_complete'),
]
My question is: Why do I keep receiving invalid links and how can I fix it?
In different questions I got answers to add the commented paths but still did not work. Any suggestions on how to fix it ?

Related

Django dj-rest-auth (django-allauth) redirection doesn't work, however, LOGIN_REDIRECT_URL is set

I'm using Django 4.1 (Djoser doesn't work with 4.x) and dj-rest-auth (if I'm not mistaken, registration is provided by django-allauth module). What am I trying to achieve is getting new user to a profile creation page ('/api/v1/new_hero/' endpoint), right after he signs up. Without any email verification, just right into it. But for now, with all theese settings, after registration, django keeps the user on the same ('auth/registration/') page with tokens demonstration and other stuff. By the way, situation keeps similar with loginning. How am I supposed to direct the user to a target page?
settings.py:
DEFAULT_AUTO_FIELD = 'django.db.models.BigAutoField'
REST_USE_JWT = True
JWT_AUTH_COOKIE = 'jwt-auth'
SITE_ID = 1
LOGIN_REDIRECT_URL = '/api/v1/new_hero/'
ACCOUNT_SIGNUP_REDIRECT_URL = '/api/v1/new_hero/'
ACCOUNT_AUTHENTICATED_LOGIN_REDIRECTS = True
ACCOUNT_EMAIL_VERIFICATION = 'none'
urls.py
urlpatterns = [
re_path(r'^docs(?P<format>\.json|\.yaml)$', schema_view.without_ui(cache_timeout=0), name='schema-json'),
re_path(r'^docs/$', schema_view.with_ui('swagger', cache_timeout=0), name='schema-swagger-ui'),
re_path(r'^redoc/$', schema_view.with_ui('redoc', cache_timeout=0), name='schema-redoc'),
path('admin/', admin.site.urls),
path('api-auth/', include('rest_framework.urls')),
path('api/v1/', include('items.urls')),
path('auth/', include('dj_rest_auth.urls')),
path('auth/registration/', include('dj_rest_auth.registration.urls')),
]
items/urls.py
urlpatterns = [
path('items/', ItemsListCreateView.as_view(), name='list_items'),
path('items/<int:pk>/', ItemDetailView.as_view(), name='update_item'),
path('heroes/', HeroListView.as_view(), name='list_heroes'),
path('new_hero/', HeroCreateView.as_view(), name='create_hero'),
path('heroes/<int:pk>/', HeroDetailView.as_view(), name='update_hero'),
path('classes/', HeroClassListCreateView.as_view(), name='list_classes'),
path('weapons/', WeaponClassListCreateView.as_view(), name='list_weapons'),
# path('reg/', Registration.as_view(), name='custom_registration'),
]
I tryied different django-allauth settings, checked correctness of INSTALLED_APPS, AUTHENTICATION_BACKENDS and other sections of settings.py, and it all end up here, with me writing a question.

Django Didn't ask for password_reset_confirm template

I am following Corey Schafer Video lecture >> Password Reset Email
urls.py
from django.contrib import admin
from django.contrib.auth import views as auth_views
from django.urls import path, include
from users import views as user_views
from django.conf import settings
from django.conf.urls.static import static
urlpatterns = [
path('admin/', admin.site.urls),
path('', include('blog.urls')),
path('profile/', user_views.profile, name='profile'),
path('register/', user_views.register, name='register'),
path('login/', auth_views.LoginView.as_view(template_name='users/login.html'), name='login'),
path('logout/', auth_views.LogoutView.as_view(template_name='users/logout.html'), name='logout'),
path('password-reset/', auth_views.PasswordResetView.as_view(
template_name='users/password_reset.html'), name='password_reset'),
path('password-reset/done/', auth_views.PasswordResetDoneView.as_view(
template_name='users/password_reset_done.html'), name='password_reset_done'),
path('password-reset-confirm/<uidb64>/<token>/',
auth_views.PasswordResetConfirmView.as_view(
template_name='users/password_reset_confirm.html'),
name='password_reset_confirm'),
]
if settings.DEBUG:
urlpatterns += static(settings.MEDIA_URL,
document_root=settings.MEDIA_ROOT)
AND CREATED 3 HTML FILE for these routes
but as per his lecture >> then he hit button (request reset password) he's getting error like noReverseMatch Reverse for 'password_reset_confirm' bla bla bla
then he created another route to handle this which is ('password-reset-confirm///')
but in my case
when i hit button request reset pasword it throw me to this route
"password-reset/done/" (with no error ,no email has been sent )
settings.py
EMAIL_BACKEND = 'django.core.mail.backends.smtp.EmailBackend'
EMAIL_HOST = "smtp.gmail.com"
EMAIL_PORT = 587
EMAIL_USE_TLS = True
EMAIL_HOST_USER = config.EMAIL
EMAIL_HOST_PASSWORD = config.PASS
For those who struggled like me with this email sending tutorial: If you don't receive any email and don't get any error, it seems like Django won't send an email if the email address you submit in the form doesn't match the email registered for the user in the DB (specified in the profile and admin pages).
In other words, I had no errors when I was reseting the passowrd but I wasn't receiving any emails neither. After a few hours struggeling, I just changed user email adress so that it matches the one I wanted to send email to and it worked. (Ack to Elijah Mayorov in utube comment)

Django url/route order not maintained

I have the following in my root URLconf module (there's more, but not important, so left out):
urlpatterns = [
re_path(r'^password-reset-redirect-view/(?P<uidb64>[0-9A-Za-z_\-]+)/(?P<token>[0-9A-Za-z]{1,13}-[0-9A-Za-z]{1,20})/$',
password_reset_redirect,
name = 'password_reset_confirm'),
path('', include('search.urls')),
path('', include('customer_portal.urls')),
path('rest-auth/', include('rest_auth.urls')),
path('rest-auth/registration/', include('rest_auth.registration.urls')),
Here's the customer_portal.urls:
urlpatterns = [
path('customer/contact/', views.contact),
path('', views.home),
re_path(r"^confirm-email/(?P<key>[-:\w]+)/$", views.email_verification,
name="account_confirm_email"),
]
Here's the rest_auth.registration.urls:
urlpatterns = [
url(r'^$', RegisterView.as_view(), name='rest_register'),
url(r'^verify-email/$', VerifyEmailView.as_view(), name='rest_verify_email'),
url(r'^account-confirm-email/(?P<key>[-:\w]+)/$', TemplateView.as_view(),
name='account_confirm_email'),
]
As you can see both included urls.py urlpatterns have a view named 'account_confirm_email'.
Somewhere in the code this is ran:
url = reverse(
"account_confirm_email",
args=[emailconfirmation.key])
Since customer_portal.urls is included before rest_auth.registration.urls, I expect the route account_confirm_email in customer_portal.urls to be returned by the above reverse method. But instead I get the rest_auth.registration.urls route URL.
Just to be sure I commented out the route in rest_auth.registration.urls, and then I did get the correct URL (customer_portal URL) returned.
It is filled into an email, I check that email and see that I have the wanted url: http://127.0.0.1:8000/confirm-email/......./, instead of: http://127.0.0.1:8000/rest-auth/registration/account-confirm-email/...../
Can anyone tell me why the customer_portal URL isn't the one being reversed in both cases?
Django docs say:
Django runs through each URL pattern, in order, and stops at the first one that matches the requested URL.

Remove user endpoints in Django rest auth

I am using Django rest auth for user account handling. For updating user info i have created custom endpoints, So i don't need the djnago-rest-auth generated endpoints /rest-auth/user/ (GET, PUT, PATCH). How can i remove these endpoints?
urls.py
urlpatterns = [
path('', include("rest_auth.urls"), name="user-auth"),
path('register', include('rest_auth.registration.urls'), name="user-auth-registration"),
path('<uid>/', views.UserProfileView.as_view(), name="user-profile"),
]
Edit
I want to use all other urls of rest-auth like login, register, etc. But i just dont want the /rest-auth/user/ as described here.
#bodoubleu 's answer didn't work, So i added them manually.
from rest_auth.views import (
LoginView, LogoutView, PasswordChangeView,
PasswordResetView, PasswordResetConfirmView
)
urlpatterns = [
path('register', include('rest_auth.registration.urls'), name="user-auth-registration"),
path('login', LoginView.as_view(), name="user-login"),
path('logout', LogoutView.as_view(), name='user-logout'),
path('password/change/', PasswordChangeView.as_view(), name='rest_password_change'),
path('password/reset', PasswordResetView.as_view(), name='rest_password_reset'),
path('password/reset/confirm/', PasswordResetConfirmView.as_view(), name='rest_password_reset_confirm'),
path('<uid>/', views.UserProfileView.as_view(), name="user-profile"),
]
Untested but this should work.
urlpatterns = [
path('user/', django.views.defaults.page_not_found),
path('', include("rest_auth.urls"), name="user-auth"),
path('register', include('rest_auth.registration.urls'), name="user-auth-registration"),
path('<uid>/', views.UserProfileView.as_view(), name="user-profile"),
]
If not you can manually define all the rest_auth.urls in your url patterns

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

I'm trying to use allauth and rest-auth in my project and try to use the built-in function in allauth to do email verification but this what I get :
and here is my code
settings.py
ACCOUNT_EMAIL_VERIFICATION = 'mandatory'
ACCOUNT_EMAIL_REQUIRED = True
urls.py
urlpatterns = [
re_path(r'^', include('rest_auth.urls')),
re_path(r'^registration/', include('rest_auth.registration.urls')),
]
I found the solution, that I have to add URL to be able to make a post request to the backend to send email then URL with regex which has the token that will verify the account and URLs and add URL for login with name account_login and URL for register with name account_signup and be like this :
from rest_auth.registration.views import VerifyEmailView, RegisterView
urlpatterns = [
path('', include('rest_auth.urls')),
path('login/', LoginView.as_view(), name='account_login'),
path('registration/', include('rest_auth.registration.urls')),
path('registration/', RegisterView.as_view(), name='account_signup'),
re_path(r'^account-confirm-email/', VerifyEmailView.as_view(),
name='account_email_verification_sent'),
re_path(r'^account-confirm-email/(?P<key>[-:\w]+)/$', VerifyEmailView.as_view(),
name='account_confirm_email'),
]
I had the same issue but I already had set up the URL for the email confirmation but I forgot about the name parameter it is mandatory
from django.conf.urls import url, include
from dj_rest_auth.registration.views import VerifyEmailView
urlpatterns = [
url('auth/', include('dj_rest_auth.urls')),
url('auth/registration/', include('dj_rest_auth.registration.urls')),
url('auth/account-confirm-email/', VerifyEmailView.as_view(), name='account_email_verification_sent'),
]
ยดยดยด