Reputation: 536
Django version 3.2
I have created a AbstractUser model for storing info of Bank's Customer . I am able to register the customer with username and password . But it's not getting authenticated while login . In admin page the password is saved as plain text , which is not expected . It should be saved in hashed form by default in Django . Please give some directions to solve this . What I am doing wrong ?
In settings.py I have added line :
AUTH_USER_MODEL = 'banking.Customer'
models.py :
'''
This stores all customers of this bank .
'''
class Customer(AbstractUser):
#username = models.CharField(max_length=128, unique=True)
#first_name = models.CharField(max_length=128)
#last_name = models.CharField(max_length=128)
#email = models.CharField(max_length=128)
phone = models.CharField(max_length=128)
#password = models.CharField(max_length=2048)
dateJoined = models.DateTimeField(auto_now_add=True)
# completed, pending, blocked, error
verificationStatus = models.CharField(max_length=128)
#USERNAME_FIELD = 'username'
#REQUIRED_FIELDS = []
def __str__(self):
return f"{self.username}, {self.first_name} {self.last_name}, {self.email}, {self.password}"
views.py :
def register(request):
if request.method == "POST":
# get the information from form
print("POST request :" + str(request.POST))
userName = request.POST["userName"]
firstName = request.POST["firstName"]
lastName = request.POST["lastName"]
email = request.POST["email"]
phone = request.POST["phone"]
password = request.POST["password"]
# insert it in DB, keep in mind that username should be unique
try:
customer = Customer(username=userName, first_name=firstName, last_name=lastName, email=email, phone=phone, password=password, verificationStatus="verified")
customer.save()
print("Database " + str(customer))
return HttpResponseRedirect(reverse('login'))
except:
# send register page agin with error message
context = {"message": userName + " userName is already taken ."}
return render(request, "banking/register.html", context)
else:
return render(request, "banking/register.html")
def login(request):
if request.method == "POST":
# get info from login form
username = request.POST["userName"]
password = request.POST["password"]
# check if user is valid
customer = None
try:
# check if userName exist in DB
print("check user")
customer = authenticate(request, username=username, password=password)
except:
customer = None
# save customer in session
if customer is not None:
login(request, customer)
return HttpResponseRedirect(reverse('mainPage'))
else:
# return to login page with error message
context = {"message": "Invalid credentials"}
return render(request, "banking/login.html", context)
else:
return render(request, "banking/login.html")
Upvotes: 1
Views: 1177
Reputation: 605
When creating the custom User
class in Django, password encryption and saving mechanism should be handled by the Manager class.
See the code used from the EmployeeManager
class in the astikgabani/Inventory-Management repository.
Upvotes: 0
Reputation: 186
In your register() method of views.py, you have to edit your code to be:
customer = Customer(username=userName, first_name=firstName, last_name=lastName, email=email, phone=phone, verificationStatus="verified")
customer.set_password(password)
customer.save()
While saving user, we have to set passwords using set_password() method, as it will save password using appropriate hash/encryption algorithm.
Upvotes: 2
Reputation: 21807
You create the customer by using the models __init__
method (the constructor):
customer = Customer(username=userName, first_name=firstName, last_name=lastName, email=email, phone=phone, password=password, verificationStatus="verified")
But this does not consider the fact that the password needs to be hashed and saves the password as plain text. This causes your user to be unable to login as the authenticate
function works on the premise that the password is hashed.
You should instead use the create_user
[Django docs] method of the user model's manager, UserManager, which will automatically hash the password:
customer = Customer.objects.create_user(username=userName, first_name=firstName, last_name=lastName, email=email, phone=phone, password=password, verificationStatus="verified")
Upvotes: 0