Reputation:
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
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