I'm trying to create a login form for my website, but I cannot log into any existing account.
def loginPage(request):
if request.method == 'POST':
username = request.POST.get('username')
password = request.POST.get('password')
try:
user = User.objects.get(username=username)
except:
messages.error(request, 'User does not exist')
user = authenticate(request, username=username, password=password)
if user is not None:
login(request, user)
return redirect('home')
else:
messages.error(request, 'Invalid username/password')
context = {}
return render(request, 'base/login_register.html', context)
Even if I use the correct credentials, it will display:
User does not exist
Invalid username/password
I've also added this to my settings.py:
AUTHENTICATION_BACKENDS = (
'django.contrib.auth.backends.ModelBackend',
)
I've created those accounts manually from the Django admin account, not with a registration form, could this be the issue?
I found the problem. In the html login file, I was missing name="username" and name="password" in the corresponding inputs.
Related
Views.py
def Tourist_login(request):
if request.method == 'POST':
form = Tourist_login_form(request.POST)
if form.is_valid():
username = form.cleaned_data['username']
password = form.cleaned_data['password']
user = authenticate(username=username,password=password)
print(user)
if user is not None:
login(request,user)
messages.success(request,'logged in')
return redirect('home')
else:
messages.error(request,"Invalid login credentials!")
return redirect('touristlogin')
else:
return redirect('touirstlogin')
else:
form = Tourist_login_form()
return render(request,'accounts/tourist_login.html',{'form':form})
In the above code , authenticate function returns none value. But if I'm passing input in form through superuser credentials then it is working fine. I'm not able why is it not taking the username and password passed by the user and only taking superuser username and password.
Please try using this way:
from django.contrib.auth.models import auth
user = auth.authenticate(username=username, password=password)
if user is not None:
auth.login(request, user)
messages.success(request,'logged in')
return redirect('home')
I want the registered user to log in with the Email or PhoneNumber and the Password first. If the user forgot the Password then there should be the possibility to log in with OTP bypassing the Password which would be provided via SMS on the User Phone Number. So Is there any possibility to achieve that?
Here are official docs where the password field is always required.
https://docs.djangoproject.com/en/4.0/topics/auth/customizing/#a-full-example
I know we can change the username to the email or for a phone number if we want but how do we put the condition to login with Password/Random OTP. So how we can achieve that? a suggestion would be appreciated. Thanks
You can make your own CustomLoginBackend as
from django.contrib.auth import get_user_model
class CustomLoginBackend(object):
def authenticate(self, request, email, password, otp):
User = get_user_model()
try:
user = User.objects.using(db_name).get(email=email)
except User.DoesNotExist:
return None
else:
if password is not None:
if getattr(user, 'is_active', False) and user.check_password(password):
return user
else:
if getattr(user, 'is_active', False) and user.otp == otp: #<-- otp included in user table
return user
return None
Then in your login views.
from django.contrib.auth import authenticate, login
from django.contrib import messages
def login_view(request):
if request.method == 'POST':
email = request.POST.get('email', None)
password = request.POST.get('password', None)
otp = request.POST.get('otp', None)
user = authenticate(request, email=email, password=password, otp=otp)
if user is not None:
login(request, user)
# redirect to a success page
return redirect('dashboard')
else:
if password is not None:
# return either email or password incorrect
messages.error(request, "Invalid Email or Password")
return redirect('login')
else:
# return invalid otp
messages.error(request, "Invalid OTP")
return redirect('login')
return render(request, 'login.html')
And at last don't forgot to add AUTHENTICATION_BACKENDS in your settings.py as
AUTHENTICATION_BACKENDS = ['path_to_your.CustomLoginBackend ',]
Yes we can do that using forced login here is an example how i have did this please have a look i have a profile which is one to one relation with user
def login_otp(request):
mobile = request.session['mobile']
context = {'mobile':mobile}
if request.method == 'POST':
otp = request.POST.get('otp')
profile = Profile.objects.filter(mobile=mobile).first()
if otp == profile.otp:
user = User.objects.get(id = profile.user.id)
login(request , user)
return redirect('cart')
else:
context = {'message' : 'Wrong OTP' , 'class' : 'danger','mobile':mobile }
return render(request,'login_otp.html' , context)
return render(request,'login_otp.html' , context)
Here is the login method in the view:
def login(request):
if request.method == 'POST':
username = request.POST['username']
password = request.POST['password']
user = auth.authenticate(username=username, password=password)
if user is not None:
auth.login(request, user)
return redirect('forum')
else:
messages.info(request, 'Username or password is wrong!')
return render(request, 'login.html')
return render(request, 'login.html')
Here is how I wrote my codes:
In the views module: I've register method and login method which both work properly.
However, I've other methods who required login in order to access them, since I redirect only a page at a time, I can't get the same username across the pages that required login before to access them.
Now the problem is, how to create another page who treats data came from the forum by conserving the same username from the loggin.
PS: In the forum, I can get the username but how to maintain the same username, is the problem
Thanks :)
If I understood the issue, you want to use user after login.
def login(request):
if request.method == 'POST':
username = request.POST['username']
password = request.POST['password']
user = auth.authenticate(username=username, password=password)
if user is not None:
auth.login(request, user)
return redirect('forum')
else:
messages.info(request, 'Username or password is wrong!')
return render(request, 'login.html')
return render(request, 'login.html')
def another_page(request, *args, **kwargs):
user = request.user
...
In every template you can get username from user object:
{% if user.is_authenticated %}
{{ user.username }}
{% endif %}
user is an object that django shares to it's templates
I collect two forms at signup - a register form and a user profile form.
The form submission works alright - I get to see the new user and their profile on the admin panel. The problem would be automatically logging them in and redirecting them to a specific page doesn't seem to work.
This is what my views.py file look like:
def registerView(request):
regForm = RegisterForm
proForm = UserProfileForm
if request.method == 'POST':
regForm = RegisterForm(request.POST)
proForm = UserProfileForm(request.POST)
if regForm.is_valid() and proForm.is_valid():
user = regForm.save(commit=True)
profile = proForm.save(commit=False)
profile.user = user
profile.save()
username = request.POST.get('username')
password = request.POST.get('password')
user = authenticate(username=username, password=password)
if user:
if user.is_active:
login(request, user)
return render (request, 'main/dashboard.html', {})
else:
return HttpResponse("There was a problem signing you up!")
regDic = {'regForm': regForm, 'proForm': proForm}
return render(request, 'person/register.html', context=regDic)
What would be the best way to automatically log in & redirect the registered user upon form submission?
Try using redirect instead of render.
from django.shortcuts import redirect
if user:
if user.is_active:
login(request, user)
return redirect('name of the url you want to redirect')
First use the cleaned_data from the valid form instead of getting the raw values and then instead of render the template redirect to some path after the successful login.
And also the authenticate function should have request as the first parameter.
username = regForm.cleaned_data.get('username')
password = regForm.cleaned_data.get('password')
user = authenticate(request, username=username, password=password)
if user is not None:
login(request, user)
return redirect('some_path')
I have a django app and I am trying to integrate the login system that they have within the framework. I have the following line of code:
user = authenticate(username=username, password=password)
login(request, user)
I am running this method right after I create a new user after the user signs up and creates an account. I know the authentication is going to be successfull because I just created the account and I know it is there. I am gettting the following error
login() takes 1 positional argument but 2 were given
In the documentation is says you pass in a request and user... so why is it not working. this is driving me crazy....
Here is the documentation on djangos websites:
login(request, user, backend=None)[source]¶
To log a user in, from a view, use login(). It takes an HttpRequest object and a User object. login() saves the user’s ID in the session, using Django’s session framework.
Note that any data set during the anonymous session is retained in the session after a user logs in.
This example shows how you might use both authenticate() and login():
from django.contrib.auth import authenticate, login
def my_view(request):
username = request.POST['username']
password = request.POST['password']
user = authenticate(request, username=username, password=password)
if user is not None:
login(request, user)
Here is my full signup method:
def signup(request):
if request.method == 'POST':
form = SignupForm(request.POST)
if form.is_valid():
cd = form.cleaned_data
username = cd['username']
password = cd['password']
verify = cd['verify']
email = cd['email']
if password == verify:
secure_password = make_password(password)
user = User.objects.create(
username = username,
password = secure_password,
email = email,
)
user = authenticate(username=username, password=password)
if user is not None:
login(request, user)
else:
return redirect('home')
else:
form = SignupForm()
parameters = {
'form':form,
}
return render(request, 'users/signup.html', parameters)
else:
form = SignupForm()
parameters = {
'form':form
}
return render(request, 'users/signup.html', parameters)
if you havent declared any function with the same name as login
then
user = authenticate(request, username=username, password=password)
if user is not None:
login(request, user)
you missed the request in the authenticate.
and if you have declared a function with the name login then change it to something else