How to authenticate django user in my custom password reset system? - python

I building an password reset system for my users. An password reset code sending to user mail and now I want to authenticate user by this code. If user enter the right code then password will be change otherwise not.
I am also storing the verification code in my models fields.
models.py:
class UserProfile(models.Model):
user = models.ForeignKey(settings.AUTH_USER_MODEL,on_delete=models.CASCADE,related_name="userprofile")
forget_password_token = models.CharField(max_length=100,blank=True,null=True)
views.py I am sending the code to user mail and also storing the same code in my models fields
def ForgetPasswordSendCode(request):
if request.method == "POST":
email = request.POST["email"]
User = get_user_model()
if not User.objects.filter(email=email).first():
messages.success(request, "Invalid mail")
return redirect('members:reset-password')
user_obj = User.objects.get(email=email)
reset_code = str(rand_number_mail()) #generating random code
profile_obj = UserProfile.objects.get(user=user_obj)
profile_obj.forget_password_token = reset_code
profile_obj.save()
current_site = get_current_site(request)
subject = 'Verification Code'
context = {
'user_first_name': user_obj.first_name ,
'user_last_name': user_obj.last_name ,
'domain': current_site.domain,
'reset_code': reset_code
}
html_body = render_to_string('mail/resetpassword-mail.html', context)
to_email = request.POST["email"]
email = EmailMultiAlternatives(subject=subject,from_email='noreply#farhyn.com',to=[to_email])
email.attach_alternative(html_body, "text/html")
email.send(fail_silently=False)
messages.success(request, "An password reset code sent to your email")
return redirect('members:change-password') #redirecting user to password reset page after submitting mail.
return render(request, 'members/password_reset_form.html')
Now I am stuck in password reset view where user insert the code and change his password. I am not undersealing how to authenticate user by verification code.
def ChangePassWordPage(request):
return render(request,'members/password_change.html')

This might helps
Step1: Send user your code and code must have a reference of your user so it will be easy to cross check
Step2: if your code match with your user (this case act as a authentication )
Step3: update your user model with new password (make_password)
UPDATE
def ChangePassWordPage(request):
if request.method == "POST":
email = request.POST["email"]
user_token = request.POST["token"]
User = get_user_model()
if not User.objects.filter(email=email).first():
messages.success(request, "Invalid mail")
return redirect('members:reset-password')
user_obj = User.objects.get(email=email)
token = UserProfile.objects.filter(user = user_obj).first().forget_password_token
if token == user_token:
#update your user password
else:
return redirect('members:reset-password')
return render(request,'members/password_change.html')
In step 2, your token will act as authentication means, token will just verify the user and token to match and if that matches then you just update the password.
And this will authorized you to update your password
Yes Same as it is!!
You don't authenticate the user by the verification code. You get the matching user object by the code and chance the password. –
Klaus D.

Related

Django login authentication always returns none

I am using django contrip auth for authenticate user. Signup function always working and register and login user successfully but after that I m logged out and try to login again but this time login function doesnt work.
I add this codes my settings file
AUTHENTICATION_BACKENDS = (
'django.contrib.auth.backends.ModelBackend',
)
AUTH_USER_MODEL = 'app.User'
My User model seems like that in models.py
class User(AbstractUser):
pass
My Login and Register function
def dlogin(request):
if request.method=='GET':
return render(request, "login.html")
if request.method == "POST":
username = request.POST['username']
password = request.POST['password']
# Attempt to sign user in
user = authenticate(request, username=username, password=password)
print(user)
# Check if authentication successful
if user is not None:
login(request, user)
cur_user = request.user
return render(request,'index.html',{
'success':'login successful',
'user':cur_user
})
else:
return render(request,'login.html',{
'error':'Invalid username and/or password.'
})
#csrf_exempt
def signup(request):
if request.method != "POST":
return render(request, 'signup.html')
# Get form information
username = request.POST["username"]
password = request.POST["password"]
confirmation = request.POST["confirmation"]
# Ensure password matches confirmation
if password != confirmation:
return render(request,'register.html',{
'message':'Passwords dont match'
})
# Attempt to create new user
user = User.objects.create_user(username,password)
user.save()
login(request, user)
return redirect('index')
I did some research and couldn't find any problem in my code. Does anyone can help me?
I fixed it
I change this in signup function
user = User.objects.create_user(username,password)
to this
user = User.objects.create_user(username=username,password=password)
and it works but i dont know why

Django Do I need to take any step for secure my user password?

I setup an password reset system in my django website. Where user first need to submit his email address then my website sending an password rest code to his email. He need to be enter his verification code and new password in password reset page. If he entered right verification code then his password will be change and redirect to login page.
I have few question:
is there any security risk in my password reset system?
How .set_password() working for save user password? does it using any encryption method?
Most important question: can user change his user_id during changing password? if yes then how to stop him to change password password if user_id changed?
here is my code:
the first function sending verification code to user email:
def ForgetPasswordSendCode(request):
if request.method == "POST":
email = request.POST["email"]
User = get_user_model()
if not User.objects.filter(email=email).first():
messages.success(request, "Invalid mail")
return redirect('members:reset-password')
user_obj = User.objects.get(email=email)
reset_code = str(rand_number_mail())
profile_obj = UserProfile.objects.get(user=user_obj)
profile_obj.forget_password_token = reset_code
profile_obj.save()
current_site = get_current_site(request)
subject = 'Password Reset Code'
context = {
'user_first_name': user_obj.first_name ,
'user_last_name': user_obj.last_name ,
'domain': current_site.domain,
'reset_code': reset_code
}
html_body = render_to_string('mail/resetpassword-mail.html', context)
to_email = request.POST["email"]
email = EmailMultiAlternatives(subject=subject,from_email='noreply#farhyn.com',to=[to_email])
email.attach_alternative(html_body, "text/html")
email.send(fail_silently=False)
messages.success(request, "password reset code sent to your email address")
return redirect('members:change-password')
return render(request, 'members/password_reset_form.html')
This second function changing user password. User need to be enter his verification code and new password.
def ChangePassWordPage(request):
User = get_user_model()
try:
if request.method == "POST":
forget_password_token = request.POST["forget_password_token"]
password1 = request.POST["password1"]
password2 = request.POST["password2"]
if not UserProfile.objects.filter(forget_password_token=forget_password_token):
messages.warning(request, "Invalid Code. Enter the correct code without any space")
if password1 != password2:
messages.warning(request,"The two password fields didn’t match")
return redirect('members:change-password')
user_profile = UserProfile.objects.get(forget_password_token=forget_password_token)
user_id = user_profile.user_id
user_obj = User.objects.get(id=user_id)
if password1 == password2:
user_obj.set_password(password1)
user_obj.save()
reset_code = str(rand_number_mail())
user_profile.forget_password_token = reset_code
user_profile.save()
messages.success(request,"Your password sucessfully changed")
return redirect('members:login')
except Exception as e:
print('wrong user')
return render(request,'members/password_change.html')
Yes it does. Django system is pretty safe if used correctly.
If you planning to do some customizations you really need to know what you are doing.
Here are the docs from Django:

I am working on python django and have a registration form there are fields like username email password want to check if exists

I have a html form where there are fields like username, email, password I want to check individually if username exists or not by entering username also email exists or not by entering email in the html form also check both at same time if both exists or not the code I have written for this is not working for single field what I meant is if I enter only username it says username is taken also email is taken But I don't want that I want individually they exists or not and if I enter both existing email and username it should say email is taken and username is taken by displaying message. How can I modify the code to work like that
This is my views.py code
def Register(request):
try:
if request.method == 'POST':
username = request.POST.get('username')
email = request.POST.get('email')
password = request.POST.get('password')
try:
email_taken = User.objects.filter(email=email).exists()
username_taken = User.objects.filter(username=username).exists()
if email_taken:
messages.error(request,"Email is taken.")
if username_taken:
messages.error(request,"Username is taken.")
if email_taken or username_taken:
return redirect('/register/')
user_obj = User(username = username , email = email)
user_obj.set_password(password)
user_obj.save()
profile_obj = Profile.objects.create(user = user_obj )
profile_obj.save()
return redirect('/login/')
except Exception as e:
print(e)
except Exception as e:
print(e)
return render(request , 'register.html')
if you want to check username and password in form and show error before he/she submit form,you have to use ajax to send request for every field that you have..unfortunately i havent example to show you but you got the idea..search for ajax in django.

How to manage users that put wrong email in registration but saved in the database

I write some code to register a user. In my fonction "register(request)", Before i do email verification i save the user and he is saved in the database but he is not active. Then i use this user to activate him in my function "activate(request)" and i activate the user.
But there is a problem, if the user put a wrong or not email, he will be saved in database, and this can take useless memory space in database. And the other problem is that if the user want to correct his informations on registration page, he will not be able to do that because his username and email already exists in database.
EDIT
By saying that he puts a wrong email is in the case he put username#gmail.com instead of user_name#gmail.com. The email is entered and is in the good format but that is not his email
def register(request):
registered = False
if request.method == 'POST':
form = UserForm(data=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 = 'Activez votre compte acquisitor.'
message = render_to_string('users/acc_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 render(request, 'users/mail_registration.html')
else:
print(form.errors)
else:
form = UserForm()
return render(request, 'users/registration.html', {'user_form': form,
'registered': registered})
def activate(request, uidb64, token, backend='django.contrib.auth.backends.ModelBackend'):
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
registered = True
user.save()
login(request, user, backend)
return HttpResponseRedirect(reverse('index'))
else:
return HttpResponse("Lien d'activation invalide")
if the user put a wrong or not email
Your form should validate that the email field is filled and at least formally correct, so the only possibility is that the user mistyped his email. A common and effective solution (albeit slightly annoying from user's perspective) is to put 2 email fields in the form and check if they match in the form's clean() data.
At this point, if the user still managed to get it wrong, he won't get the activation mail anyway, so there's not much you can do - except eventually adding a cron job to remove users that never activated their accounts (based on active status, creation date and last login date).

Django: Create new user account

I'm having some trouble creating a new account and then logging in. I enter all the credentials in (first_name, last_name, username, password), and select "Create new account", and it successfully redirects me back to the login page. However, when I try to login with this new account, it says that my username doesn't exist.
The problem is most likely in my views.py file:
def create_account(request):
if request.method == 'POST':
new_user = User(username = request.POST["username"],
password = request.POST["password"])
new_user.save()
Student.objects.create(user=new_user,
first_name=str(request.POST.get("first_name")),
last_name=str(request.POST.get("last_name")))
new_user.is_active = True
return redirect('../')
else:
return render(request, 'polls/create_account.html')
Let me know if you guys need any more code or information. Thanks!
The password field needs to be encrypted. If you are going to set the password, you need to use set_password() method that will deal with encryption.
new_user = User(username = request.POST["username"])
new_user.set_password(request.POST["password"])
new_user.save()
this another option if you work in form with cleaned_data:
def create_account(self, request):
if request.method == 'POST':
form = RegisterForm(request.POST) #registration form
if form.is_valid():
cd = form.cleaned_data
username = cd['username']
password = cd['password']
new_user = User.objects.create_user(
username = cd['username'],
password = cd['password']
)
new_user.save()
#... do stuff

Categories