how to use user authentication in django - python

i have a html template which i want to use for authentication in django. I am using pymongo to connect to remote mongodb and fetch_data. The remote mongodb has a collection which has username & password for a demo user. I read that django has a inbuilt authentication module but i dont want to use that.
My template :
<form action="/index.html">
<div class="form-group">
<div class="input-group">
<div class="input-group-addon"><i class="fa fa-user"></i></div>
<input type="text" class="form-control" placeholder="Username">
</div>
</div>
<div class="form-group">
<div class="input-group">
<div class="input-group-addon"><i class="fa fa-asterisk"></i></div>
<input type="password" class="form-control" placeholder="Password">
</div>
</div>
<div class="row">
<div class="col-xs-8 text-left checkbox">
<label class="form-checkbox form-icon">
<input type="checkbox"> Remember me
</label>
</div>
<div class="col-xs-4">
<div class="form-group text-right">
<button class="btn btn-success text-uppercase" type="submit">Sign In</button>
</div>
</div>
</div>
</form>
How can i pass data from my template to my views.py file? Currently I am not using any authentication.
my views.py:
from django.shortcuts import render
from django.http import HttpResponse
def login(request):
return render(request, 'login/login.html')
In Pymongo, I can use command db.getCollection('users').find({'email':'%s'}) {{email}} to pass email and verify.
PS: Most tutorial i read were about django's inbuilt authentication.

The generic way is to write custom authentication backend which handles authentication for you. Then it is recommended to create custom form which is rendered in your template.
Authentication backend
class YourBackend(object):
def authenticate(self, username=None, password=None):
# Check the username/password and return a User.
def get_user(self, user_id):
# return user by given user_id
Settings
When you have implemented your own authentication backend you should define it inside django settings.py. The first one is django's default authentication backend.
AUTHENTICATION_BACKENDS = (
'django.contrib.auth.backends.ModelBackend',
'your.own.authentication.backed',
)
Form
from django import forms
class YourLoginForm(forms.Form):
username = forms.CharField(max_length=254)
password = forms.CharField(label=_("Password"), widget=forms.PasswordInput)
View
from django.shortcuts import render
from django.http import HttpResponse
from django.contrib.auth import authenticate, get_backends
def login(request):
form = YourLoginForm(request.POST or None)
if form.method == 'POST':
if form.is_valid():
user = authenticate(username=form.cleaned_data['username'], password=form.cleaned_data['password'])
if user:
# redirect user to somewhere
return render(request, 'login/login.html')
Template
<form action="{% url 'your-login' %}" method="POST">
{{ form.non_field_errors }}
<div class="form-group">
<div class="input-group">
{{ form.username.errors }}
<div class="input-group-addon"><i class="fa fa-user"></i></div>
{{ form.username }}
</div>
</div>
<div class="form-group">
<div class="input-group">
{{ form.username.errors }}
<div class="input-group-addon"><i class="fa fa-asterisk"></i></div>
{{ form.password }}
</div>
</div>
<div class="row">
<div class="col-xs-4">
<div class="form-group text-right">
<button class="btn btn-success text-uppercase" type="submit">Sign In</button>
</div>
</div>
</div>
</form>
Urls
url(r'^login$', 'views.login', name='your-login'),

I suggest you to use external libraries for authentication and profiling. As I remember they have got options for mongodb. But if you want to reinvent the wheel, then you should use following.
1) Create class that extends form.ModelForm to handle registration and authentication process. You could read documentation how to do it. If will help you to handle validation of the data. You'll able to validate unique email fields and other stuff.
2) Create HTML form. You could use existing and just connect it with your ModelClass.
3) If you're using forms you could get data just with following command in yor controller:
form = MyForm(request.POST or None)
Then you'll be able to pass data to this form. If you don't want to use and form classes then you could retrieve if in such way in your controller:
if request.method == 'POST':
login = request.POST.get('login', None)
password = request.POST.get('password', None)
Assign controller with the form you could using urls.py, just the same way:
url(r'^login$', 'views.login', name='login'),
So using forms class you'll be able to pass empty form when GET request arrived and if it's POST request then you could collect data. Also, add to your HTML form following:
<form action="/login" method="post">
4) When you receive data from your login form you should authenticate. This could be done using custom authentication backend. You could find info here or just Google how to do it. I've never done it before, but it's pretty simple.

Related

Django users can't login after I create an account but admin can and i didnt create any registration form by only manually can add users

I've created a login page as a homepage and only by adding manually in Django administration can create a user. I didn't create a registration form and message error else statement in home viwes.py is working on the admin panel. If I login by user, I get CSRF token error
homepage
views.py
from django.shortcuts import redirect, render
from loginapp.models import Register
from django.contrib import messages
from django.contrib.auth import authenticate, login , logout
def home(request):
if request.method == 'POST':
username = request.POST['username']
password = request.POST['password']
user = authenticate(request,username=username, password=password)
if user is not None:
login(request, user)
return render(request, "home.html")
else:
messages.error(request, "Bad Creds!!")
return redirect('/')
return render(request, "home.html")
login page views.py
def index(request):
return render(request, "index.html")
login page name as index.html
<form id="stripe-login" method="POST" action="{% url 'home' %}">
{% csrf_token %}
<div class="trick" style="padding-bottom: 10px;">
<input type="text" name="username" required>
<label for="email">Username</label>
</div>
<div class=" trick" style="padding-bottom:10px;">
<input type="password" name="password" required>
<label for="password">Password</label>
</div>
<div class="field" style="padding-bottom:10px; padding-top: 10px;">
<input type="submit" name="submit" value="Continue">
</div>
<div class="reset-pass" style="padding-top: 20px;">
Forgot your password?
</div>
<div class="footer-link text-light" style="padding-top:10px;">
<span>
Don't have an account?
<a href="{% url 'signup' %}">
Request for a new account
</a>
</span>
</div>
</form>
for creating user you must use
User.objects.create_user() method
Ex: User.objects.create_user(username=username,email=email,password=password)

Unable to Authenticate login page in Django when created a new database using Models.py

I have created a new table using models.py and this table stores data to my models.py table which I created.
Now when I am going to my login page its not able to authenticate the details from that table and always gives invalid credentials.
My app name which I created is User and the table name which is stored in SQLite is User_register
Login.html
<div class="wrapper gradient">
<div class="container">
<div class="row centered-form">
<div class="col-xs-12 col-sm-8 col-md-4 col-sm-offset-2 col-md-offset-4">
<div class="panel panel-default">
<div class="panel-heading">
<h3 class="panel-title"><center><b>Login To Web App!!</b></center> </h3>
</div>
<div class="panel-body">
<form role="form" method="POST">
{% csrf_token %}
<div class="form-group">
<input type="text" name="email" id="email" class="form-control input-sm" placeholder="Username">
</div>
<div class="form-group">
<input type="password" name="password" id="password" class="form-control input-sm" placeholder="Password">
</div>
<div class="form-group">
{% for message in messages %}
<p style="color:black;">{{message}}</p>
{% endfor %}
</div>
<input type="submit" value="Login" class="btn btn-info btn-block">
</form>
</div>
</div>
</div>
</div>
</div>
</div>
Models.py
class Register(models.Model):
first_name = models.CharField(max_length=90)
last_name = models.CharField(max_length=90)
email = models.EmailField(max_length=90)
password = models.CharField(max_length=90)
Views.py
def login(request):
if request.method == 'POST':
email = request.POST['email']
password = request.POST['password']
user = auth.authenticate(email=email, password=password)
if user is not None:
auth.login(request, user)
return render(request,'index.html')
else:
messages.info(request, 'Invalid credentials')
return render(request,'login.html')
else:
return render(request, 'login.html')
I may be out of touch, but
the fields youre using are premade in the standard auth backend which you easily set to use those fields. A good tutorial for this is apart of this youtube series https://youtube.com/playlist?list=PLzMcBGfZo4-kQkZp-j9PNyKq7Yw5VYjq9
Or check out a extended example with password reset etc in the register app of this repo https://github.com/HarryLudemann/Job-Search
If you still require making your own custom model i suggest you using a 'custom authbackend' this is nearly always the way togo unless you use the prebuild form check it ou here https://docs.djangoproject.com/en/3.2/topics/auth/customizing/
If You still want to use the setuo youre using you should be using the built in forms, this allows you to use the cleaned_data method check out the docs https://docs.djangoproject.com/en/3.2/ref/forms/fields/
Or look for a example in the github repo above.
If this does not answer help please post any more code, errors or info you have. Also ensure you have run the makemigrations and migrate aswell as mugrate your server setup. Hope this somewhat helps 👍

Django Authentication LDAP

I have a Django project in which I want to authenticate users against an Active Directory. Therefore, I am using the django-python3-ldap framework. I am able to sync users(./manage.py ldap_sync_users), grant superuser admin access, and login to the default Django admin page using the framework as backend. However, when I try to authenticate on my site, the user state remains AnonymousUser.
views.py
def login(request):
try:
username = request.POST['username']
password = request.POST['password']
user = authenticate(request, username=username, password=password)
if user is not None:
login(request, user, backend=django_python3_ldap)
context = {'user': user}
return render(request, 'website/home.html', context)
else:
context = {'': ''}
return render(request, 'website/login.html', context)
except:
print()
login.html
<!-- Main content -->
<section class="hero is-success is-fullheight">
<div class="hero-body">
<div class="container has-text-centered">
<div class="column is-4 is-offset-4">
<div class="box">
<figure class="avatar">
<img src="">
</figure>
<form method="post">
{% csrf_token %}
<div class="field">
<div class="control">
<input class="input is-large" type="text" placeholder="Username" autofocus="">
</div>
</div>
<div class="field">
<div class="control">
<input class="input is-large" type="password" placeholder="Password">
</div>
</div>
<div class="field">
<label class="checkbox">
<input type="checkbox">
Remember Me
</label>
</div>
<button class="button is-block is-danger is-info is-large is-fullwidth">Login</button>
{% endblock %}
</form>
</div>
</div>
</div>
</div>
</section>
imports
from django.contrib.auth import authenticate, login
import django_python3_ldap
backend
AUTHENTICATION_BACKENDS = ('django_python3_ldap.auth.LDAPBackend',)
urls.py
path('login', auth_views.login, {'template_name': 'website/login.html'}, name='login'),
I see possibly two issues the backend is not pointing to a valid backend. Also your try except is a bit dangerous please remove it. Unless you are testing never use a blank except. Use something like except Exception as e: print(e). The reason I say that is the blank except was hiding the invalid backend error.
login(request, user, backend=django_python3_ldap)
# Should be
login(request, user, backend=django_python3_ldap.auth.LDAPBackend)

Django redirect after login

Im creating my first app in Django
I decided I want logging window (smal one with username/password na "Log in" button) on EACH view.
From base.html:
<div id="logging">
{% if user.is_authenticated %}
<h1>Witaj, {{user.username}}!</h1>
{% else %}
<form method="post" action="{% url 'harcowanie.views.login' %}">
{% csrf_token %}
<div style="display: inline-block;">
<p><label for="id_username">Username:</label> <input id="id_username" type="text" name="username" maxlength="30" /></p>
<p><label for="id_password">Password:</label> <input type="password" name="password" id="id_password" /></p>
</div>
<div style="display: inline-block; position: relative; bottom: 25px;">
<input class="decent_background" type="submit" value="Log in" />
</div>
</form>
{% endif %}
</div>
Any part of my views.py:
def login(request):
username = request.POST['username']
password = request.POST['password']
user = authenticate(username=username, password=password)
if user is not None:
if user.is_active:
login(request=request, user=user)
return redirect(request.META['HTTP_REFERER'], context_instance=RequestContext(request))
else:
pass
# Return a 'disabled account' error message
else:
pass
# Return an 'invalid login' error message.
return redirect(request.META['HTTP_REFERER'], context_instance=RequestContext(request))
But I'm getting error:
A {% csrf_token %} was used in a template, but the context did not
provide the value. This is usually caused by not using
RequestContext. warnings.warn("A {% csrf_token %} was used in a
template, but the context did not provide the value. This is usually
caused by not using RequestContext.")
Looks like you use redirect in wrong way. Argument context_instance is not supported by this method. See docs.
About error. Ensure that view which rendered page from request.META['HTTP_REFERER'] uses RequestContext or manually import and use the processor to generate the CSRF token(docs).
The error states that the CSRF token is not in your context. A good read to know what CSRF is about: here.
In order to generate the CSRF token, either enable the middleware in your settings, or generate by hand in your view, then pass it to your template. I strongly suggest to you to enable the middleware :)

Django login required twice

I'm making a webpage where I login and add people to an address book. Once I login and click on the "add address" button, I'm redirected back to the login page with the following url:
http://localhost:8000/xcard/login/?next=/xcard/add_address/
If I login again I can get to account page, address book, and then add_address book page without being caught in the login loop. I can logout and login and add addresses without relogin in twice. But the first time I ever login I have to do it twice. Not sure if it's a problem with the login or the add address code.
Views.py
class LoginView(View):
def get(self, request):
''' if user is authenticated '''
if request.user.is_authenticated():
return render(request, 'xcard/account.html')
else:
return render(request, 'xcard/login.html')
def post(self, request):
username = request.POST['username']
password = request.POST['password']
user = authenticate(username=username, password=password)
state = "The email or password is incorrect"
if user is not None:
login(request, user)
return HttpResponseRedirect('/xcard/account/')
else:
return render(request, 'xcard/login.html', {'state':state})
class AddAddressView(View):
def get(self,request):
address_form = AddressForm()
friend_form = FriendForm()
return render(request, 'xcard/add_address.html', {'friend_form':friend_form, 'address_form':address_form})
def post(self,request):
address_form = AddressForm(request.POST)
friend_form = FriendForm(request.POST)
if address_form.is_valid() and friend_form.is_valid():
new_address = address_form.save()
new_friend = friend_form.save(commit=False)
new_friend.address = new_address
new_friend.save()
return HttpResponseRedirect('/xcard/address_book')
else:
return render(request, 'xcard/add_address.html', {'state' : "Failed", 'friend_form':friend_form, 'address_form':address_form})
Templates:
address_book.html
{% include "xcard/header.html" %}
{% block main %}
<div class="container">
<h3 class="text-info"><u>Your Account</u></h3>
Add
Import
</div>
{% endblock %}
Templates:
login.html
{% extends "xcard/base.html" %}
{% block main %}
<div class="container">
<div class="row space">
<p class="text-center lead text-warning">
Login page</p>
<p class="text-center text-info">Trusted worldwide!</p>
</div>
<div class="row">
<div class="span offset4">
<form class="well" action="/xcard/login/" method="post">
{% csrf_token %}
<p class="lead">Sign In</p>
<fieldset class="login_page">
<p class="text-error"><strong>{{ state }}</strong></p>
<label class="control-label" for ="inputIcon">Email</label>
<div class="controls">
<div class="input-prepend">
<span class="add-on"><i class="icon-user"></i></span>
<input type="text" class="span3" id="ernainputIcon" required name="username" placeholder="Username...."/><br/><br/>
</div>
</div>
<label>Password</label>
<div class="controls">
<div class="input-prepend">
<span class="add-on"><i class="icon-lock"></i></span>
<input type="password" class="span3" id="inputIcon" required name="password" placeholder="Password...."/><br/><br/><br />
</div>
</div>
<button class="btn btn-primary">Sign In</button>
Not a user?
Sign up
</fieldset>
</form>
</div>
</div>
</div>
{% endblock %}
I just found this in my urls.py
url(r'^add_address/$', login_required(AddAddressView.as_view(), login_url='/xcard/login/')),
Maybe this is causing the problem? But why doesn't it register that I'm already logged in?
first do the correction in AddAddressView function. update line
return render(request, 'xcard/add_address.html', {'friend_form':friend_form, 'address_form':address_form})
it will work
This was my solution - logout before you try to authenticate.
This issue happened to me when users were logging in and logging back in with a different username.
import django.contrib.auth as djangoAuth
djangoAuth.logout(request) # logout
user = djangoAuth.authenticate(username=username, password=password) # login

Categories

Resources