Django authenticate is None - django

def user_login(request):
if request.method == "POST":
user_name = request.POST.get("username",'')
pass_word = request.POST.get("password",'')
user = authenticate(user_name=user_name,password=pass_word)
if user is not None:
login(request,user)
return render(request,'index.html')
else:
return render(request,'login.html',{ })
elif request.method == "GET":
return render(request,"login.html",{ })
I've already set up the super user and updated the database, but the backstage password user still returns None

authenticate function takes arguments in form:
authenticate(username='john', password='secret').
change
user_name -> username
in arguments

the default authenticate looks like this
from django.contrib.auth import authenticate
user = authenticate(username='john', password='secret')
if user is not None:
# A backend authenticated the credentials
else:
# No backend authenticated the credentials
so i think you need to change username if you're not overriding it

user = authenticate(username=user_name,password=pass_word)
In this line the authenticate function has username=user_name not user_name=user_name as argument. I think this might be the issue.
Hope this helps :-)

Related

How to use check_password function in django

I'm a beginner in Django. I have a signup form with only 2 fields. Username and Password. The password is encrypted using the pbkdf2_sha256 algorithm.
I want to login using the username and password.so the password that I'm inputting in the login page must be checked with the encrypted password. How to do that?. Also, please explain what authenticate and check_password function does?
def save(request):
if request.method == 'POST':
name = request.POST.get('name')
password = request.POST.get('pass')
enc_pass = pbkdf2_sha256.encrypt(password,rounds=12000,salt_size = 32)
a = signup(username = name, password = enc_pass)
a.save()
return render(request,'save.html')
def login(request):
if request.method == 'POST':
username = request.POST.get('user')
password1 = request.POST.get('password1')
p = check_password(password=password1)
if signup.objects.filter(username__exact=username).exists() and p is True:
return HttpResponse("Success")
else:
return HttpResponse("Invalid Credentials")
return render(request, 'login.html')
You can do:
if check_password(password_user_entered, request.user.password):
# You can authenticate
Here, password_user_entered is password that came from the request(or, pw to be checked). And, request.user.password which is the password with which we want to compare.
check_password does not work like this. To make it work, you need to use Django's own authentication system. If you are concerned about using pbkdf2_sha256, Django provides this hasher. To use this with you own auth system, add it to settings:
PASSWORD_HASHERS = [
'django.contrib.auth.hashers.PBKDF2SHA1PasswordHasher',
'django.contrib.auth.hashers.PBKDF2PasswordHasher',
'django.contrib.auth.hashers.Argon2PasswordHasher',
]
And in django authentication, you do not need to hash it manually, django will take care of it itself. All you need to do is save the user like this:
from django.contrib.auth.models import User
user = User.objects.create_user(username=username, email=email, password=password, #.. other required fields)
And to check password:
user = User.objects.get(username=username)
user.check_password(password)
More information can be found in documentation

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 Cookie with Login function

I'm trying to set my first cookie with Django when users are logged on my application.
When user is logged, the template is well-displayed but none cookie in my application which is named : Cookie
My function looks like :
def Login(request):
error = False
if request.method == "POST":
form = ConnexionForm(request.POST)
if form.is_valid():
username = form.cleaned_data["username"]
password = form.cleaned_data["password"]
user = authenticate(username=username, password=password)
if user:
login(request, user)
toto = GEDCookie(request)
return render(request, 'Home_Homepage.html', {'toto':toto})
else:
error = True
else:
form = ConnexionForm()
return render(request, 'Authentication_Homepage.html', locals())
#csrf_exempt
def GEDCookie(request):
SID = Logger.login("test", "10test")
response = HttpResponse("Cookie")
response.set_cookie('Cookie', SID, max_age=None)
return response
I missed something in my script ?
This isn't how you use cookies at all.
Inside your Login view, you're calling a separate view - GEDCookie that returns an HTTP response. But instead of returning that response directly to the user, which would set the cookie, you're for some reason trying to insert it in a template. That doesn't make sense.
If you want to set a cookie in your login view, you need to do so on the response that you return to the user.
Note also that after a successful login (or other post), you should always redirect, not display a template directly. So:
if user:
login(request, user)
response = redirect('home')
response.set_cookie('whatever')
return response
Finally, you almost certainly don't need a cookie here in any case. If you want to store data related to the current user, use the session.
As you can clearly see that you are not attaching your cookie to your real response, you are passing it as the context in render function which is an issue.
def Login(request):
error = False
if request.method == "POST":
form = ConnexionForm(request.POST)
if form.is_valid():
username = form.cleaned_data["username"]
password = form.cleaned_data["password"]
user = authenticate(username=username, password=password)
if user:
login(request, user)
SID = Logger.login("test", "10test")
response = render(request, 'Home_Homepage.html', {})
response.set_cookie('Cookie', SID, max_age=None)
return response
else:
error = True
else:
form = ConnexionForm()
return render(request, 'Authentication_Homepage.html', locals())
https://docs.djangoproject.com/en/3.0/ref/request-response/#django.http.HttpResponse.set_cookie Please refer this link for individual arguments of inbuilt function.
Create signal.py in app. where your user model is present or add in main project directory and Add below snippet in signal.py
from django.db.models.signals import pre_save, pre_delete, post_save, post_delete
from django.dispatch import receiver
from django.dispatch import Signal
from allauth.account.signals import user_logged_in # it signal for post login
from django.shortcuts import render
#receiver(user_logged_in) # Decorator of receiving signal while user going to logged in
def post_login(sender, user, request, response, **kwargs):
response.set_cookie('team', 'india') # This will set cookie
return response
In given snippet, default response will come in argument, so direct redirect to that response, if you want to change then render other template using render/redirect django.shortcuts methods like below,
response = render(request, 'base.html', {})

django and angularJS permission_required anonymousUser

i'm writing a django / angularjs application, and i'm trying to use the #permission_required for user permission authorization.
I'm returning from the client side both headers- sessionId and csrf token, and yet the #permission_required method user, is anonymousUser, although when i'm logging in the user, i use - login(request, user) method, and the user arg is updated to the current user:
#api_view(['GET', 'POST', 'DELETE'])
def log_in_view(request):
body = request.body
json_body = json.loads(body)
email = json_body.get("email")
password = json_body.get('password')
user = authenticate(email=email, password=password)
session = request.session
if user is not None:
request.session['email'] = email
request.session['password'] = password
session.set_expiry(900)
session.save()
session_key = session.session_key
login(request, user)
crcf = get_token(request)
response_body = {}
response_body.update({"session_key" : session_key})
response_body.update({"csrf" : crcf})
return HttpResponse(json.dumps(response_body), content_type="text/json", status=200)
else:
return HttpResponse("could not authenticate user", content_type="text/plain", status=401)
does anyone have any idea what am i doing wrong?
cheers
you dont need all those stuff to login the user. I mean you dont need to set up session manually, either return csrf token.
#api_view(['GET', 'POST', 'DELETE'])
def log_in_view(request):
body = request.body
json_body = json.loads(body)
email = json_body.get("email")
password = json_body.get('password')
user = authenticate(email=email, password=password)
if user:
login(request, user)
response_body = {}
response_body['user'] = user
return HttpResponse(json.dumps(response_body), content_type="text/json", status=200)
else:
return HttpResponse("could not authenticate user", content_type="text/plain", status=401)
By use of #api_view I'm assuming that you're using Django REST Framework.
Each api view of django rest framework don't rely by default on django authentication. If you want your view to use django authentication, you should add proper #authentication_classes(...) decorator to your view or specify it globally in your settings.py file.

How to establish Django session using Tastypie ApiKeyAuthentication?

I want to use Tastypie's ApiKeyAuthentication to authenticate a request and then establish a session for the user within a Django view. I have username and api_key for the user. I do not have the user's password. This is the code I currently have:
class ApiKeyPlusWebAuthentication(ApiKeyAuthentication):
def is_authenticated(self, request, **kwargs):
isAuthenticated = super(ApiKeyPlusWebAuthentication, self).is_authenticated(request, **kwargs)
if isAuthenticated:
print request.user.email
return isAuthenticated
#login for access from UIWebView
def login_usingApiKeyAuthentication(request):
auth = ApiKeyPlusWebAuthentication(request)
if auth.is_authenticated(request):
print 'authenticated'
login(request, request.user)
return redirect(reverse(view_name))
else:
print 'NOT authenticated'
messages.error(request, MESSAGE_INVALID_LOGIN)
fail_redirect = redirect(reverse('login'))
return fail_redirect
I am getting an error 'User' object has no attribute 'backend'. This is because I haven't called authenticate(user, password). I am using the Django default authentication backend.
In this scenario, I only have APIKey associated with the user and don't have the raw password for authentication.
One way to handle this may be to create custom authentication backend that bypasses password requirement. However, registering a "password-less" authentication backend in settings.py seems like a hack prone to security breakdown.
So, how can I use ApiKeyAuthentication and then authenticate & login the user in Django establishing a session?
I found a solution to set the backend in another post. You can set the custom backend directly on the user object.
from django.contrib.auth.backends import ModelBackend
from django.contrib.auth.models import User
class PasswordlessAuthBackend(ModelBackend):
"""Log in to Django without providing a password.
"""
def authenticate(self, username=None):
try:
return User.objects.get(username=username)
except User.DoesNotExist:
return None
def get_user(self, user_id):
try:
return User.objects.get(pk=user_id)
except User.DoesNotExist:
return None
#csrf_exempt
def login_uiwebview(request):
auth = ApiKeyPlusWebAuthentication(request)
if auth.is_authenticated(request):
view_name = request.POST.get('view_name')
request.user.backend = 'app.views.PasswordlessAuthBackend'
login(request, request.user)
return redirect(view_name)
else:
print 'NOT authenticated'
messages.error(request, MESSAGE_INVALID_LOGIN)
fail_redirect = redirect(reverse('login'))
return fail_redirect