DJango: authenticate function vs verifying username, password and is_active - django

I am working on a Django Project:
I have a login form with username and password
Generally i observed authenticate function is used to authenticate a user and pass i.e
user = authenticate(username, password)
I tried to understand the authenticate function but i found it is not so easy.
Instead of using the authenticate function i want to check the authentication the following way:
1) check if the username exists
2) check if the password matches
3) check if is_active is true.
Which i can do by the following way:
username = self.cleaned_data.get('username')
password = self.cleaned_data.get('password')
# check if user exists
try:
user = User.objects.get(username=username)
except User.DoesNotExist:
user = None
#check if user is_active
if user.is_active:
user_active = true
else
user_active = false
#check the password
if user_active:
password_match = user.check_password(password):
else:
password_match = false
if password_match:
msg = "Login Successful"
else:
msg = "Login Failed"
Will the above serve the same purpose as authenticate function or is there something else to be checked.

authenticate method runs through all authenticate backends and call it's authenticate method.
Default Django's auth backend is ModelBackend. If you check it's authenticate method you'll see that it's already include all described by you steps.

Related

Django authenticate method returns None

I am trying to create a user login. I am registering the user through django's admin page. Username and passwords are entered correctly.
Also I have tried adding authentication backends to settings.py
I have tried multiple ways but couldn't get it to work.
AUTHENTICATION_BACKENDS = (
'django.contrib.auth.backends.ModelBackend',
)
My code looks like below :
models.py :
class Account(models.Model):
user = models.OneToOneField(User, on_delete=models.CASCADE)
views.py:
def login(request):
if request.method == 'POST':
username = request.POST.get('user')
password = request.POST.get('pass')
user = authenticate(username=username,
password=password) ----------> None
if user:
if user.is_active():
login(request, user)
return HttpResponseRedirect(reverse('index'))
else:
return HttpResponse('Account not active')
else:
print('Someone tried to login and failed ')
print('Username {} and passowrd {}'.format(username, password))
return HttpResponse('Invalid login details supplied!!')
else:
return render(request,'account/login.html', {})
The username and password from the below ones are coming as empty so it is giving none
username = request.POST.get('user')
password = request.POST.get('pass')
Try to inspect the element from HTML to find the name of the fields from which the data is coming from the template or print the values of username and password variables to cross verify.
use request.POST.get('username'), request.POST.get('password1') but as told it totally depends on the html template. It is safer to clean the data and then go for authentication.
Django has inbuilt Class Based Views for the same purpose. Give them a try

Django - Authenticate with custom User model returns None

I'm following a tutorial (https://thinkster.io/tutorials/django-json-api/authentication) on setting up authentication. I've got to the point where I'm registering users and receiving the tokens back. I can drop into the shell and do;
>>> user = Users.objects.first()
>>> user.email
>>> test#outlook.com
>>> user.password
>>> 12345678
This shows that the user exists in the database. But when calling my login endpoint;
/users/login/
the authenticate method returns None.
user = authenticate(username=email, password=password)
I'm printing the email and password just before and it shows the correct data passed in.
I've also set my USERNAME_FIELD to email in my model.
USERNAME_FIELD = 'email'
I've updated my model in my settings to be
AUTH_USER_MODEL = 'aemauthentication.User'
I've had a look around and the above line in the settings file seems to be the approved answer for most people with this issue.
GitHub link to project - https://github.com/Daniel-sims/aem_1
As per; Django User Creation successful, but authenticate() returning None
I'd changed the create_user method to take the password as a parameter;
user = self.model(username=username, email=self.normalize_email(email), password=password)
but you have to call set password, so everythings working fine with;
user = self.model(username=username, email=self.normalize_email(email))
user.set_password(password)

How do I create a Login System in Django Using Sessions?

I am trying to create a website which is authenticated by a custom login. But I have a custom Model for users. How do I authenticate my Website from anonymous Users. Is it possible to create login systems using based on sessions. Actually this is my first django project. Please Guide me. Thank you.
While login, after checking username and password create a session in which set their user object or it's object id in it. In this case i kept user id.
def login(request):
if request.method == "GET":
if (Users.objects.filter(username = request.GET.get("uname"), password = request.GET.get("upswd"))).exists():
user = Users.objects.get(username = request.GET.get("uname"), password = request.GET.get("upswd"))
request.session["user"] = user.id
# request.session.set_expiry(10)
# it shows home page
return render(request,"home.html")
#it shows again login page
return render(request,"Login.html")
only in login page you will set session, In remaining you will check whether page contains that session or not.For example, in after login in home page you should check whether request contains user session or not.
if request.session.has_key("user"):
userid = request.session["user"]
#displaying all items in database
context={"items":Products.objects.all()}
return render(request,"home.html",context)
It is better to use a POST form instead of a GET request as against the answer above. Also, instead of querying for username and password against your database, use authenticate() function.
from django.contrib.auth import authenticate, login
if request.POST:
if login_form.is_valid():
username = request.POST.get('username')
password = request.POST.get('password')
user = authenticate(username=username, password=password)
if user:
login(request, user)
# do something or redirect
You don't need to set the user id in the session object, to retrieve the currently logged in user, use request.user

want to improve my view

I've view like this. It worked. I'm new to django. Can you please help me to improve this code? thank you
def getAPI(request):
username = request.GET.get('username')
password = request.GET.get('password')
#TODO Match user and password
if username:
user = User.objects.get(username__exact=username)
is_exist = user.check_password(password)
if is_exist == True:
api_key = ApiKey.objects.get(id=user.id)
else:
error_message = 'username or password is invalid.'
return render_to_response('details.html',locals(),
context_instance=RequestContext(request)
)
if username and password does not exist Then I want to print error message. Otherwise I want to print ApiKey. thanks
Do you mean "print" (in which case just use python's print function) or do you want to return it in the response? If the latter, read up about django templates and passing variables to render_to_response.
Also, sticking a password as a GET variable is a bit of a bad idea, since it'll be visible on the URL:
http://example.com/whatever?username=me&password=s3cr3t
User/pass info should normally be sent via POST from a form. But maybe you're not that bothered about security.
Here's the basic template to authenticate a user:
from django.contrib.auth import authenticate
def my_view(request):
username = request.POST['username']
password = request.POST['password']
user = authenticate(username=username, password=password)
if user is not None:
if user.is_active:
# User is authenticated - return api key
else:
# Return a 'disabled account' error message
else:
# Return an 'invalid login' error message.

Problem with custom Authentication Backend for Django

I'm having a problem with a custom Authentication Backend I've built for an Active Directory via LDAP authentication.
The problem is that from the admin login page, after it properly authenticates and creates the new user in the database (or updates their info from the LDAP server), but then returns me to the admin login page indicating that I failed to enter a valid username and password.
Considering it authenticates and creates/updates the user in the django database, what am I doing wrong?
The code:
import ldap
import re
from django.conf import ad_settings
grps = re.compile(r'CN=(\w+)').findall
def anyof(short_group_list, adu):
all_groups_of_user = set(g for gs in adu.get('memberOf',()) for g in grps(gs))
return any(g for g in short_group_list if g in all_groups_of_user)
class ActiveDirectoryBackend(ModelBackend):
"""
This backend utilizes an ActiveDirectory server via LDAP to authenticate
users, creating them in Django if they don't already exist.
"""
def authenticate(self, username=None, password=None):
con = None
ldap.set_option(ldap.OPT_REFERRALS, 0)
try:
con = ldap.initialize('ldap://%s:%s' % (ad_settings.AD_DNS_NAME,
ad_settings.AD_LDAP_PORT))
con.simple_bind_s(username+"#"+ad_settings.AD_DNS_NAME, password)
ADUser = con.search_ext_s(ad_settings.AD_SEARCH_DN,
ldap.SCOPE_SUBTREE,
"sAMAccountName=%s" % username,
ad_settings.AD_SEARCH_FIELDS)[0][1]
con.unbind()
except ldap.LDAPError:
return None
# Does user belong to appropriate AD group?
if not anyof(ad_settings.PROJECTCODE,ADUser):
return None
# Does user already exist in Django?
try:
user = User.objects.get(username=username)
except User.DoesNotExist:
#create Django user
user = User(username=username, is_staff = True, is_superuser = False)
#Update User info from AD
if ADUser.has_key('givenName'):
user.first_name = ADUser.get('givenName')[0]
if ADUser.has_key('sn'):
user.last_name = ADUser.get('sn')[0]
if ADUser.has_key('mail'):
user.email = ADUser.get('mail')[0]
# Does not store password in Django.
user.set_unusable_password()
user.save()
return user
EDIT: Figured out. Users cannot log in unless they are active (even though the documentation does not say that). Therefore, in the code given, the line that creates the new user should look like:
user = User(username=username, is_staff = True, is_Active = True,
is_superuser = False)
Figured out. Users cannot log in unless they are active (even though the documentation does not say that). Therefore, in the code given, the line that creates the new user should look like:
user = User(username=username, is_staff = True, is_Active = True,
is_superuser = False)