user21135338
user21135338

Reputation:

Email verification fails everytime in django project

I am making a project in Django in which I need the users to go through an email verification. The email verification link is being generated and sent to the user on the email provided on signup. However when the confirm_email function(provided below) is called to check, it always results in failure(failure.html is shown everytime).

def confirm_email(request, uidb64, otp):
    try:
        uid = force_bytes(urlsafe_base64_decode(uidb64))
        user = User.objects.get(pk=uid)
        print(user, uid, otp)
    except (TypeError, ValueError, OverflowError, User.DoesNotExist):
        user = None

    if user and default_token_generator.check_token(user, otp):
        user.is_active = True
        user.save()
        return render(request, 'path to email_confirmation_success.html')
    else:
        return render(request, 'path to email_confirmation_failure.html')

What can be the issue here? I have printed the token generated in signup_page function and it is the same as the one being generated in the link sent to user

singup_page function:

def signup_page(req):
if req.method == 'POST':
    form = CustomUserCreationForm(req.POST)
    if form.is_valid():
        user = form.save(commit=False)
        user.is_active = False
        user.save()

        #Generating otp
        otp = generate_otp(user)
        print(otp)

        #Building email confirmation URL
        cur_site = get_current_site(req)
        # uid = urlsafe_base64_encode(user.pk)
        # otp_encoded = urlsafe_base64_decode(force_bytes(otp))

        confirm_url = f"http://{cur_site.domain}/confirm-email/{(user.pk)}/{otp}/"

        # Load and render the HTML template
        template = loader.get_template('path to confirm-email.html')
        context = {'user': user, 'confirm_url': confirm_url}
        message = template.render(context)

        #Email to be sent
        subject = "Confirm your email"

        #to_email = form.cleaned_data.get('email')
        email = EmailMultiAlternatives(subject, '', to=[user.email])
        email.attach_alternative(message, "text/html")
        email.send()

        return redirect('landing:new')
    
    else:
        form = CustomUserCreationForm()
    return render(req, 'path to signuppage.html', {'form': form})

urls.py:

from django.contrib import admin
from django.urls import path, include
import sys
sys.path.append("D://OSO//CP Analyzer//cp_analyzer//landing")
from landing import views
from django.contrib.auth import views as auth_views

urlpatterns = [
    path('admin/', admin.site.urls),
    path('', views.homepage, name='home'),
    path('landing/', include('landing.urls')),
    path('confirm-email/<str:uidb64>/<str:token>/',views.confirm_email, name='confirmation'),
    path('password-reset/', auth_views.PasswordResetView.as_view(), name='password_reset'),
    path('password-reset/done/', auth_views.PasswordResetDoneView.as_view(), name='password_reset_done'),
    path('reset/<uidb64>/<token>/', auth_views.PasswordResetConfirmView.as_view(), name='password_reset_confirm'),
    path('reset/done/', auth_views.PasswordResetCompleteView.as_view(), name='password_reset_complete'),
]

Upvotes: 0

Views: 273

Answers (1)

skdishansachin
skdishansachin

Reputation: 714

I think the problem is with your urls.py file.

path('confirm-email/<str:uidb64>/<str:token>/',views.confirm_email, name='confirmation'),

Here you're using token as the name for the token parameter, but in the view, you're referring to it as otp.

In your views.py file update the confirm_email function argument to token like below instead of otp.

def confirm_email(request, uidb64, token):

Upvotes: 0

Related Questions