How does userena with Django track if user signed in? - django

With normal Django user handeling, you would save a session to the user once he/she is logged in. However, after reading the userena views.py file for signin, I couldn't see how the user is tracked so that once they log in, the site would now they are logged in. I put the code from userena below:
def signin(request, auth_form=AuthenticationForm,
template_name='userena/signin_form.html',
redirect_field_name=REDIRECT_FIELD_NAME,
redirect_signin_function=signin_redirect, extra_context=None):
"""
Signin using email or username with password.
Signs a user in by combining email/username with password. If the
combination is correct and the user :func:`is_active` the
:func:`redirect_signin_function` is called with the arguments
``REDIRECT_FIELD_NAME`` and an instance of the :class:`User` whois is
trying the login. The returned value of the function will be the URL that
is redirected to.
A user can also select to be remembered for ``USERENA_REMEMBER_DAYS``.
:param auth_form:
Form to use for signing the user in. Defaults to the
:class:`AuthenticationForm` supplied by userena.
:param template_name:
String defining the name of the template to use. Defaults to
``userena/signin_form.html``.
:param redirect_field_name:
Form field name which contains the value for a redirect to the
successing page. Defaults to ``next`` and is set in
``REDIRECT_FIELD_NAME`` setting.
:param redirect_signin_function:
Function which handles the redirect. This functions gets the value of
``REDIRECT_FIELD_NAME`` and the :class:`User` who has logged in. It
must return a string which specifies the URI to redirect to.
:param extra_context:
A dictionary containing extra variables that should be passed to the
rendered template. The ``form`` key is always the ``auth_form``.
**Context**
``form``
Form used for authentication supplied by ``auth_form``.
"""
form = auth_form
if request.method == 'POST':
form = auth_form(request.POST, request.FILES)
if form.is_valid():
identification, password, remember_me = (form.cleaned_data['identification'],
form.cleaned_data['password'],
form.cleaned_data['remember_me'])
user = authenticate(identification=identification,
password=password)
if user.is_active:
login(request, user)
if remember_me:
request.session.set_expiry(userena_settings.USERENA_REMEMBER_ME_DAYS[1] * 86400)
else: request.session.set_expiry(0)
if userena_settings.USERENA_USE_MESSAGES:
messages.success(request, _('You have been signed in.'),
fail_silently=True)
# Whereto now?
redirect_to = redirect_signin_function(
request.REQUEST.get(redirect_field_name), user)
return redirect(redirect_to)
else:
return redirect(reverse('userena_disabled',
kwargs={'username': user.username}))
if not extra_context: extra_context = dict()
extra_context.update({
'form': form,
'next': request.REQUEST.get(redirect_field_name),
})
return ExtraContextTemplateView.as_view(template_name=template_name,
extra_context=extra_context)(request)

The user is first authenticated using
user = authenticate(identification=identification,password=password)
which can be found here https://github.com/django/django/blob/master/django/contrib/auth/backends.py
This method checks if the user exists, and checks whether the password is correct.
If all goes well, the login method is called
login(request, user)
which can be found here
https://github.com/django/django/blob/master/django/contrib/auth/views.py
As you can see, these are two methods that are shipped with Django, and act as the sort of 'default' authentication package for Django.
Your site knows that a user is logged in because you'll probably be using Middleware (specifically SessionMiddleware and AuthenticationMiddleware), which attach a session and a user object to the request. The login method mentioned above saves the user ID to the session.
For more details see https://docs.djangoproject.com/en/dev/topics/auth/#authentication-in-web-requests
Concerning your comment:
You could render your template using RequestContext, or have your views return a TemplateResponse.
See https://docs.djangoproject.com/en/dev/ref/template-response/#using-templateresponse-and-simpletemplateresponse
This passes the user object to the template processor.
Then, in your template you could do something like this:
{% if user.is_authenticated %}
<p>Welcome {{ user.first_name }}</p>
{% else %}
<p>Please log in</p>
{% endif %}
Also see https://docs.djangoproject.com/en/dev/topics/auth/#id8
In my opinion it is indeed very well possible to put a modified version of this in your base.html. For example to show a login button if the user is not logged in, and replace it by a button that brings the user to his/her profile page when the user is logged in.

Related

login/check the username and password from database in Django website using post request

I have created a blog website where I want to login a user whose username and password are saved in a database table, named "myuser". I have already fetched the username and password from post request in my function.
Now how can I compare this value from my already created table values to check whether the username and password are correct or not?
You can't manually check the password. Because when you are creating a user, django is storing the user's password as a hash value in the database. Now if you are storing the raw password in your custom table which is myuser, it's not a good practice.
Because if someone gets access in your database, he can see the tables too. And what he will find? The precious, delicious passwords of all the users.
If you are storing the raw password i.e. mypassword12345 he just got the actual password. If you use the default django method, django will store the password like this: jkashdu12321kandsxn!312nasdkhj, for example, which is the hash for your mypassword12345. And now the attacker will see the password as jkashdu12321kandsxn!312nasdkhj this which is a hash value of your password. Django uses some strong hashing algorithm, therefore, the attacker can't easily crack your password.
So even if he gets the access of your database, he won't be able to do much except deleting documents. (which is severe but you'll be storing the backup, right?)
So if you are storing the password raw, please don't. It's for your application security.
And now, when you just got the username and password in your function which is given by your user and you want to check if the user exists or not, you can follow what #MalikFaiq suggested which is:
from django.contrib.auth.models import User
check_if_user_exists = User.objects.filter(yourtablefield="yourusername").exists()
Now if check_if_user_exists is true, it means there's a user with this username in your table. If it's false then there is no user.
Now what you'll be wanting is to check if this user is giving you the right password. You can check by doing the following:
if check_if_user_exists:
user = authenticate(request, username=username, password=password)
if user is not None:
# this user is valid, do what you want to do
else:
# this user is not valid, he provided wrong password, show some error message
else:
# there is no such entry with this username in the table
Hope it helps.
You can check user by importing model from your model class.
from django.contrib.auth.models import User
bool_answer = User.objects.filter(yourtablefield="yourusername").exists()
if bool_answer is True then it means user exists other wise not.
You need to check whether the user exists or not in your "myusertable", if yes, whether the password matches or not.
If active, exists and password matches, use the django sessions framework [most convenient] or the django cache/cookie framework to log in the user and store a session that the user is logged in.
def loginView(request):
# after checking if the user is active, exists and passwword matches
request.session["isLoggedIn"] = True
request.session["username"] = request.POST.get("username")
In your templates
Note: Make sure "django.core.context_processors.request" is in your context processors in settings.py
{% if request.session.isLoggedIn %}
{{request.session.username}}
{% else if not request.session.isLoggedIn %}
<p>User not in session or logged off</p>
{% endif %
You shouldn't store usernames/passwords on your own.
from django.http import HttpResponseForbidden
from django.contrib.auth import authenticate
# Authenticate
user = authenticate(username=username, password=password)
if user is None:
return HttpResponseForbidden()
else:
# Ready for operation
...
First, you get the email &password from the form then use table name to get all table then chose the email and password from table
if (request.method == 'GET'):
return render(request, 'login.html')
else:
email = request.POST['email']
password = request.POST['password']
intakes = Intake.objects.all().filter(email=email,password=password)
for intake in intakes:
if intake.email==email and intake.password==password:
return render(request, "nav.html")
else:
return render(request, "signup.html")

django-allauth: submitting form after social login

The current flow for visitors with django-allauth is if the visitor fills in a form, if they are not already authenticated they are shown a login modal with option of facebook login or standard signup form, with the original form data being saved in ACCOUNT_SIGNUP_FORM_CLASS=SignupForm
class SignupForm(forms.Form):
def signup(self, request, user):
new_user = Profile()
new_user.user = user
new_user.save()
# if form data provided with signup save it.
model = self.cleaned_data['model']
if model:
# save the form
This works fine if the user signs up using the standard signup form, but if they signup using facebook social account the values from the form are now empty strings i.e. self.cleaned_data['model']. I assume the original request object is destoryed so the post data is lost? There also doesn't seem anyway to pass the form data to facebook and receive it back e.g.
<a title="{{provider.name}}" href="{% provider_login_url provider.id modal="1" process="login" next=request.path scope=scope auth_params=auth_params %}"
Is the only way to do what I want is to save the form data using local storage or the database then somehow assign it back to the visitor once registered and save it?
What I've gone with is changing the Facebook signup button to link to an intermediate view where I save the form data as session data and then redirect back to the allauth facebook login url.
I then extract the form data from the session in the signup method after the user has authenticated with facebook.

Prompting registration after creating content but before save

I am trying to implement a page using Django where the user is able to create content, hit submit, and then is prompted to register or login if they are not currently logged-in. One of the fields in the model for the content references the user, so they must be logged-in to create it, however I want them to be able to input all of the data before they are prompted with logging-in. I have used the #loginrequired decorator on the view, but that forced the user to be logged-in before they create the content. Here is the view currently:
def search(request):
form = LocationInput()
if request.method == "POST":
form = LocationInput(request.POST)
if form.is_valid():
t = Trip(trip_name = form.cleaned_data['city'])
t.user = request.user
t.save()
form.save()
l = Location.objects.get(google_id=form.cleaned_data['google_id'])
l.trips.add(t)
l.save()
return HttpResponseRedirect('/trips/')
return render(request, 'frontpage/search.html', {'form': form})
It loads the form, creates an object that needs a user associated with it so I need to register the user but keep the data from LocationInput(request.POST) until after the user has registered. Any help would be greatly appreciated!
I can see two options:
Allow NULL for user reference, save the content in a state "pending user login or sign up", and store the ID of the content object in a session. Vacuum "old" contents with no user reference on a regular basis.
Save the whole data of the form in a session.
I like the first one better since you, as a superuser, have access to the content even if the user didn't login or signup, and if the user contact you later telling you he had troubles signing in, you will be able to help and recover the content he submitted. While if everything is stored in session, once the session is deleted, it's all lost.

How to redirect the login page and check for login session in Django userena

I am new to django and to userena. I have implemented django userena and the login page which is working fine. Currently after successful login the user is redirected to profile page. I want to change this and do two things:
1. Redirect the user to the home page after successful login and not profile page and second
2. The homepage and all other pages should detect the user session and use the session variables for the particular user to customize the page.
Please let me know how should I achieve this.
THanks!
To redirect use:
USERENA_SIGNIN_REDIRECT_URL = 'your_url'
the user should always be available and you could do things like self.request.user.is_authenticated() in a view or {{ user.is_authenticated }} in a template
This is how am I doing it to check if the user is signed in.
#views.py
from userena.views import signup, signin
def sign_up(request):
#if user is authenticated, redirect to user's profile page
#otherwise use userena signup view, with my own form,SignupFormExtra, instead of userena's
if request.user.is_authenticated():
username = request.user.username
return HttpResponseRedirect('/accounts/'+username)
else:
return signup(request,signup_form=SignupFormExtra)
def sign_in(request):
if request.user.is_authenticated():
username = request.user.username
return HttpResponseRedirect('/accounts/'+username)
else:
return signin(request)
and in my urls.py I have
url(r'^accounts/signup/$', 'accounts.views.sign_up'),
url(r'^accounts/signin/$', 'accounts.views.sign_in'),

How to get the currently logged in user's user id in Django?

How to get the currently logged-in user's id?
in models.py:
class Game(models.model):
name = models.CharField(max_length=255)
owner = models.ForeignKey(User, related_name='game_user', verbose_name='Owner')
in views.py:
gta = Game.objects.create(name="gta", owner=?)
First make sure you have SessionMiddleware and AuthenticationMiddleware middlewares added to your MIDDLEWARE_CLASSES setting.
The current user is in request object, you can get it by:
def sample_view(request):
current_user = request.user
print current_user.id
request.user will give you a User object representing the currently logged-in user. If a user isn't currently logged in, request.user will be set to an instance of AnonymousUser. You can tell them apart with the field is_authenticated, like so:
if request.user.is_authenticated:
# Do something for authenticated users.
else:
# Do something for anonymous users.
You can access Current logged in user by using the following code:
request.user.id
Assuming you are referring to Django's Auth User, in your view:
def game(request):
user = request.user
gta = Game.objects.create(name="gta", owner=user)
FROM WITHIN THE TEMPLATES
This is how I usually get current logged in user and their id in my templates.
<p>Your Username is : {{user}} </p>
<p>Your User Id is : {{user.id}} </p>
I wrote this in an ajax view, but it is a more expansive answer giving the list of currently logged in and logged out users.
The is_authenticated attribute always returns True for my users, which I suppose is expected since it only checks for AnonymousUsers, but that proves useless if you were to say develop a chat app where you need logged in users displayed.
This checks for expired sessions and then figures out which user they belong to based on the decoded _auth_user_id attribute:
def ajax_find_logged_in_users(request, client_url):
"""
Figure out which users are authenticated in the system or not.
Is a logical way to check if a user has an expired session (i.e. they are not logged in)
:param request:
:param client_url:
:return:
"""
# query non-expired sessions
sessions = Session.objects.filter(expire_date__gte=timezone.now())
user_id_list = []
# build list of user ids from query
for session in sessions:
data = session.get_decoded()
# if the user is authenticated
if data.get('_auth_user_id'):
user_id_list.append(data.get('_auth_user_id'))
# gather the logged in people from the list of pks
logged_in_users = CustomUser.objects.filter(id__in=user_id_list)
list_of_logged_in_users = [{user.id: user.get_name()} for user in logged_in_users]
# Query all logged in staff users based on id list
all_staff_users = CustomUser.objects.filter(is_resident=False, is_active=True, is_superuser=False)
logged_out_users = list()
# for some reason exclude() would not work correctly, so I did this the long way.
for user in all_staff_users:
if user not in logged_in_users:
logged_out_users.append(user)
list_of_logged_out_users = [{user.id: user.get_name()} for user in logged_out_users]
# return the ajax response
data = {
'logged_in_users': list_of_logged_in_users,
'logged_out_users': list_of_logged_out_users,
}
print(data)
return HttpResponse(json.dumps(data))
This is how I usually get current logged in user and their id in my templates.
<p>Your Username is : {{user|default: Unknown}} </p>
<p>Your User Id is : {{user.id|default: Unknown}} </p>
Just go on your profile.html template and add a HTML tag named paragraph there,
<p>User-ID: {% user.id %}</p>