0

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'),
]

1 Answers1

0

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):
  • I did that. Please check – Animesh Singh Jul 10 '23 at 18:14
  • If you are using `token` or `opt` as the parameter in the URLs, make sure that you are using the same parameter name in the views function. – Dishan Sachin Jul 11 '23 at 05:00
  • I tried doing that, but it still redirects me to the failure html file, and I think the problem is the user is becoming None everytime, I tried printing it and it says None. But the user is being saved to the database – Animesh Singh Jul 11 '23 at 08:42
  • Did you update this URL according to the changes you made `confirm_url = f"http://{cur_site.domain}/confirm-email/{(user.pk)}/{otp}/"` (if you can provide the updated code it's going to be very helpful) – Dishan Sachin Jul 11 '23 at 08:59