Is there anyway to customise authenticate function of Django? - python

I am fairly new to Django so I wanted to know what should I do to make default authenticate function of Django accepts only email and password to login, assuming that in sign-up form I have both username and email. The following code does not work properly.However when I add
username = request.POST.get('username')
and change
user = authenticate(request, username=username email=email, password=password)
It logs in as expected.
The login View:
def LoginPage(request):
if request.method == 'POST':
email = request.POST.get('email')
password = request.POST.get('password')
user = authenticate(request, email=email, password=password)
if user is not None:
login(request, user)
print('logged')
return redirect('/inker/')
return render(request, 'authy/login.html')
The sign up view:
def SignUpPage(request):
form = CreateUserForm()
if request.method == 'POST':
form = CreateUserForm(request.POST)
if form.is_valid():
form.save()
return redirect('/login/')
context={'form':form}
return render(request, 'authy/signup.html', context)
The form module:
from django.contrib.auth.models import User
from django.contrib.auth.forms import UserCreationForm
class CreateUserForm(UserCreationForm):
class Meta:
model = User
fields = ['username','email', 'password1', 'password2']
As you can see in Sign Up view we have both username and email but in login form I want it to just login user based on only email. How can I implement this.
Also how can I compact both username and email into one input when user wants to login? pretty much like instagram, facebook login page

If you just want to access user using email, you're not using authentication on the first place. So, to solve your purpose, following approaches can be followed:
Get user email in url params in every request (so that user can be identified)
Set default password while creating the user account for all users and use that password while authentication (not recommended)

Related

Django authenticate: usage in login vs. register (signup): how do they differ?

I have noticed that the Django authenticate is used in the same way in both the login view and the register view, both return a User object to be used in the login().
In the login view authenticate() uses username and password from the submitted form, then checks on user if the credentials are ok.
if request.method == 'POST':
username = request.POST['username']
password = request.POST['password1']
user = authenticate(request, username=username, password=password)
if user is not None:
login(request, user)
The register view looks very similar to the login view. It gets the credentials from the submitted form and uses the user to login.
if request.method == "POST":
form = UserCreationForm(request.POST)
if form.is_valid():
form.save()
username = form.cleaned_data['username']
password = form.cleaned_data['password1']
user = authenticate(request, username=username, password=password)
login(request, user)
Both call user = authenticate(request, username=username, password=password).
Apart from saving the form in the register view, what is the difference here? Because the login (I guess) is only checking that the credentials are valid, but the register is creating a new user and, since it is creating, the credentials are new data coming in. Am I getting this correctly?
You do not need to authenticate a user in your register method. It can be as simple as,
form = CreateUserForm()
if request.method == 'POST':
form = CreateUserForm(request.POST)
if form.is_valid():
form.save()
return redirect('<urlname>')
context = {'form': form}
return render(request, '<appname>/<filename>.html', context)
Hence, authentication is only required while logging in as a user. And you can make your login method even simpler by doing this,
if request.method == 'POST':
username = request.POST.get('username')
password = request.POST.get('password')
user = authenticate(request, username=username, password=password)
if user:
login(request, user)
return redirect('<urlname>')
return render(request, '<appname>/<filename>.html')
Hope this clarifies the situation for you :)

import user session data to other django app

I have a django project with two apps, the first is called 'main', where the user can login and register and all the authentication stuff is made and the other is 'app' where only authenticated users can access.
Main.views:
def register(request):
if request.method == "POST":
form = UserCreationForm(request.POST)
if form.is_valid():
user = form.save()
username = form.cleaned_data.get('username')
messages.success(request, f"New account created: {username}")
login(request, user)
return redirect("app:app_index")
else:
for msg in form.error_messages:
messages.error(request, f"{msg}: {form.error_messages[msg]}")
return render(request = request,
template_name = "main/register.html",
context={"form":form})
form = UserCreationForm
return render(request = request,
template_name = "main/register.html",
context={"form":form})
All the code works fine and allows me to login, register, logout... but now I need to export that user to the 'app' app in order to use the user data on the app template, how can I migrate the user and all its data?
I wonder I would be able to just do
app.views:
from main.views import user
but definitely this does not work, any suggestion will be much appreciated
Actually you can simply access use information an all your apps with object notation.
In my case, the user object has username attribute, so when I want to use the users' username I can simply type
user.username
And it will return the username saved on the database for the specific user that's loged in

Python (Django) - Authenticate returning None

I'm using Django's authenticate function to let users register (create an account) and sign in (login after creating an account). Authenticate works fine for registration, but when I try signing the user in after logging out, it doesn't work.
Registration Method:
if request.method == 'POST':
form = SignUpForm(request.POST)
if form.is_valid():
form.save()
username = form.cleaned_data['username']
raw_password = form.cleaned_data['password1']
user = authenticate(username=username, password=raw_password) #returns user object
login(request, user) #works
Sign in Method:
if request.method == 'POST':
form = AuthenticationForm(request=request, data=request.POST)
if form.is_valid():
username = form.cleaned_data['username']
password = form.cleaned_data['password']
user = authenticate(user=username, password=password) #returns None
login(request, user) #doesn't work
I looked at a few other threads that reported a similar issue and added the following code to my settings.py file. However, authenticate still returns none when I try signing in.
settings.py code
AUTHENTICATION_BACKENDS = (
'django.contrib.auth.backends.ModelBackend',
)
As per Django documentation for authenticate method, the valid keyword arguments are username and password. Thus, I would recommend changing the following in "Sign In" method:
user = authenticate(user=username, password=password)
to
user = authenticate(request=request, username=username, password=password)

Django Python How to Compare Encrypt User's Password

I am working a project which is like CMS (Content Management System) for a website. I am developing this system with django python. But I am new to django python.
I have my own User model (not django user model) that contains some fields like username, email, password etc. and I create new user from my own admin panel.
How can I compare encrypted password with user's password that post on login page.
For example first time I create user, the password for 123 saved on db like pbkdf2_sha24123$000asd$... After that I am trying to login with password 123 but I get error that the passwords are not equals.
from django.contrib.auth.hashers import make_password
from account.models import myUsers
password = make_password(request.POST.get('password'))
email = request.POST.get('email')
if myUsers.password == password and myUsers.email == email:
#make login and redirect to panel
else:
#show error message
my own model like;
class myUsers(models.Model):
username = models.CharField(max_length=25, verbose_name='username', unique=True)
email = models.CharField(max_length=225, verbose_name='email', unique=True)
password = models.CharField(max_length=225, verbose_name='password')
created_at = models.DateTimeField(auto_now_add=True, verbose_name='created date')
secret_question = models.CharField(max_length=225, verbose_name='secret question')
secret_answer = models.CharField(max_length=225, verbose_name='secret answer')
last_login = models.DateTimeField(verbose_name='last login')
secret_guid_key = models.CharField(max_length=15, verbose_name='recover key', unique=True, editable=False, default=uuid.uuid4().hex[:15])
user_role = models.CharField(max_length=6, verbose_name='member role')
A User Object has a method called check_password() that hashes and checks your plain text password against the hashed password stored in the DB.
https://docs.djangoproject.com/en/2.2/ref/contrib/auth/#django.contrib.auth.models.User.check_password
Example Usage:
from account.models import myUsers
password = request.POST.get('password')
email = request.POST.get('email')
user = myUsers.objects.get(email=email)
if user.check_password(password):
# Success Code
else:
# Error Code
i think you should try django authenticate function.
user = authenticate(username=username, password=password)
You shuoldn't compare passwords:
if myUsers.password == password ..:
but rather the hash of the password:
if myUsers.password == myPasswordHashFunction(password) ..:
how to write myPasswordHashFunction is something you should know in detail, or you're better off using django's authenticate function.
If you're not a security expert, then please (please!) don't invent your own way to authenticate and authorize users.
try this code:
from django.contrib.auth.models import auth
from django.contrib import messages
def signin(request):
if request.method == 'POST':
username = request.POST['username']
password = request.POST['password']
user = auth.authenticate(username=username, password=password)
if user:
auth.login(request, user)
return redirect('/')
else:
messages.info(request, 'Invalid credentials!!')
return redirect('signin')
else:
return render(request, 'signin.html')
In default, the Django authentication system provided in django.contrib.auth requires the end user to authenticate themselves using a username and password.
If you're using email and password for user authentication, you need a custom authentication backend. This link will help you.
Link : https://stackoverflow.com/a/37332393/9563316
If you use username and password for user authentication. You should try something like this.
from django.contrib.auth import authenticate, login
from django.contrib import messages
def userLogin(request):
if request.method == 'POST':
username = request.POST.get('username')
password = request.POST.get('password')
user = authenticate(request, username=username, password=password)
if user is not None:
login(request, user)
return redirect('somewhere-you-want')
else:
messages.error(request, 'Invalid user login credentials!')
return redirect('userLogin')
else:
return render(request, 'login.html')
See docs here : https://docs.djangoproject.com/en/3.0/topics/auth/default/

django auth framework prepopulating form incorrectly, giving random data to fields upon load

I am trying to create a portable auth system that can be plugged in apps, and each different app I reimplement it in has the same issues.
1-Sometimes the user that recently logged in gets their sn in the email address field when a new user tries to register, as below
2- Sometimes a new user registers and logs out but the form will put the old user's email address and password in the appropriate fields, when of course I want the form to be blank if the user has logged out
3- always the last password used is filled in upon reload
I just want the form to completely clear itself when reloaded
How to clear form fields after a submit in Django
I have tried all 3 solutions from a similar question, I reinstantiated the from after saving the valid one, made a copy of request.POST and used that instead, and I was already redirecting to begin with. Here is my form
from django.contrib.auth.models import User
class UserForm(forms.ModelForm):
password = forms.CharField(widget=forms.PasswordInput())
class Meta:
model = User
fields = ('username', 'email', 'password')
in views.py
def register(request):
context = RequestContext(request)
registered = False
user_form = UserForm()
if request.method == 'POST':
pDict = request.POST.copy()
form = UserForm(pDict)
if form.is_valid():
user = form.save()
user.set_password(user.password)
user.save()
user_form = UserForm()
registered = True
username = pDict['username']
password = pDict['password']
user = authenticate(username=username, password=password)
login(request, user)
#locals isn't working? won't print user
return HttpResponseRedirect('/url/')
else:
print user_form.errors
template_name = 'accounts/register.html'
user_form = UserForm()
response = TemplateResponse(request, 'accounts/register.html', locals())
return response
thank you

Categories

Resources