Monday, January 21, 2019

User login email verification in python with reset password after successful verification

When you really need more security while making accounts and secure registration towards the system you actually need is to authenticate email address via email:

Before going through this one: please kindly visit the following blog , so that you will be a be more clear , 
# IMPORTANT

But if you want direct coding here is how this is done, :

Lets start from beginning :

lets setup email first:

inside settings.py:

EMAIL_USE_TLS=True
EMAIL_HOST='smtp.gmail.com'
EMAIL_HOST_USER='youremail'
EMAIL_HOST_PASSWORD='yourpassword'
EMAIL_PORT=587


create app account and setup basics : go to link provided above for detail:

now inside forms.py of the account app:

from django import forms
from django.contrib.auth.forms import UserCreationForm
from django.db import transaction
from account.models import User
from hotel.owner.models import HotelOwner
from hotel.staff.models import HotelStaff

class HotelOwnerSignUpForm(UserCreationForm):
email=forms.EmailField(required=True,label='Email')
first_name=forms.CharField(required=True,label='First Name')
last_name=forms.CharField(required=True,label='Last Name')
class Meta(UserCreationForm.Meta):
model=User
fields=("first_name","last_name","email","username","password1","password2")

class HotelStaffSignUpForm(UserCreationForm):
class Meta(UserCreationForm.Meta):
model=User
fields=("first_name","last_name","email","username","password1","password2")

create tokens.py inside account app

from django.contrib.auth.tokens import PasswordResetTokenGenerator
from django.utils import six
class TokenGenerator(PasswordResetTokenGenerator):
def _make_hash_value(self, user, timestamp):
return (
six.text_type(user.pk) + six.text_type(timestamp) +
six.text_type(user.is_active)
)
account_activation_token = TokenGenerator()  


Now inside urls.py  of account app


path('ResetPassword/',views.reset_account_password,name="reset_account_password"),
url(r'^activate/(?P<uidb64>[0-9A-Za-z_\-]+)/(?P<token>[0-9A-Za-z]{1,13}-[0-9A-Za-z]{1,20})/$',views.activate, name='activate'),

Inside views.py of account app
from django.shortcuts import render
from django.shortcuts import redirect
from django.views.generic import CreateView
from .forms import HotelOwnerSignUpForm
from .forms import HotelStaffSignUpForm
from django.http import HttpResponse
from account.models import User
from hotel.owner.models import HotelOwner

from django.contrib.auth import login, authenticate
from django.contrib.sites.shortcuts import get_current_site
from django.utils.encoding import force_bytes, force_text
from django.utils.http import urlsafe_base64_encode, urlsafe_base64_decode
from django.template.loader import render_to_string
from .tokens import account_activation_token
from django.core.mail import EmailMessage
from django.contrib.auth.tokens import PasswordResetTokenGenerator

def signup(request):
if request.method == 'POST':
form = HotelOwnerSignUpForm(request.POST)
if form.is_valid():
user = form.save(commit=False)
user.is_active = False
user.save()
current_site = get_current_site(request)
mail_subject = 'Activate your blog account.'
message = render_to_string('account/active_email.html', {
'user': user,
'domain': current_site.domain,
'uid':urlsafe_base64_encode(force_bytes(user.pk)).decode(),
'token':account_activation_token.make_token(user),
})
to_email = form.cleaned_data.get('email')
email = EmailMessage(
mail_subject, message, to=[to_email]
)
email.send()
return HttpResponse('Please confirm your email address to complete the registration')
else:
form = HotelOwnerSignUpForm()
return render(request, 'account/signup_form.html', {'form': form})

def activate(request, uidb64, token):
try:
uid = force_text(urlsafe_base64_decode(uidb64))
user = User.objects.get(pk=uid)
except(TypeError, ValueError, OverflowError, User.DoesNotExist):
user = None
if user is not None and account_activation_token.check_token(user, token):
user.is_active = True
user.save()
owner=HotelOwner.objects.create(user=user)
id=user.id
login(request, user)
pwtoken=PasswordResetTokenGenerator().make_token(user)
newuid=urlsafe_base64_encode(force_bytes(user.pk)).decode()
return redirect('password_reset_confirm',uidb64=newuid,token=pwtoken)
#return redirect('hotel:ownerupdate',id)
else:
return HttpResponse('Activation link is invalid!')

class HotelStaffSignUpView(CreateView):
model = User
form_class = HotelStaffSignUpForm
template_name = 'account/signup_form.html'
# print(request.user)

def form_valid(self, form):
# user = form.save()
user=form.save(commit=False)
user.is_hotel_staff=True
user.save()
owner_id=self.request.user.id
staff=HotelStaff.objects.create(user=user,owner_id_id=owner_id)
id=user.id
return redirect('hotel:staffupdate',id)



here, after you fillup signup form it, will send email a link of password reset form and on clicking that password can be changed.

now , tehre is just few steps to follow:

create active_email.html inside templates of account app and:

Hi {{ user.username }},
Please click on the link to confirm your registration,
http://{{ domain }}{% url 'activate' uidb64=uid token=token %}

this is the message you are sending to the email obtained form signup form :

all about signup forms are described on the previous blog and link of blog is provided above.



This is all we need for email verification in python django project



No comments:

Post a Comment