How to check session for all views in Django? - django

I set the session["UserID"] for user login status in view login page after pass the verify of username and password.
Then I need to check if the user is logged in within every other views, such as home page, shopping bag page and so on.
My question is, can I check it just for one time and where should I write it? Are there some methods triggered before the views called?

My question is, can I check it just for one time and where should I write it?
You do check it one time, providing you are using django's built in authentication method then the whole handling of users is done for you, you don't need session user id's since django handles the user through requests with its auth middleware.
Once logged in there will be a user as part of the request object which will either be a AnonymousUser if not logged in, or an instance of your user class if you are logged in.
Are there some methods triggered before the views called?
Yes, middlewares, which you could write your own custom middleware but I don't really think you need it.
I check the login status within the MASTER PAGE in ASP.NET and it can control all the other page which import it.
I haven't really used asp.net but again, you don't need to do this, django handles its users for you (providing your using built in auth tools).
See Limiting access to logged-in users and the functions and properties available on the user class

Related

How to implement a manual security procedure with Django

I'm writing a web application with Django framework. This web application is API based and I'm using Django rest_framework. I have a security issue: On the first page, the user must solve a Recaptcha. After solving the Recaptcha my site gives a session ID to the user and after this, the user must post this session ID in the body of all his/her API calls and every API can be called just once with a specific session ID. In other words, I have a state machine for the APIs being called by the user and in each state, the user can call the APIs which have corresponding outgoing edges from that state.
The purpose of all of the above procedures is preventing the user from crawling my website. (User can't call an API many times with a session ID and he/she should act as a normal user and call every API at most two or three times)
Now my question is that how should I handle this in my Django app? Before this, I just used the ordinary Django session middleware for handling sessions. Now should I handle the authentication process and passing and getting session ID completely in a manual way or is there a way in which I can use that middleware that it can be able to handle my procedure.
You can do this with simply with saving your user's state and in each step update your user's state and consider the next states which user can see.
Use custom permission classes for your APIViews to block such request.
Read more here https://www.django-rest-framework.org/api-guide/permissions/#custom-permissions

Django: what are some good strategies for persisting form input across login?

I have a webapp that allows authenticated as well as anonymous users to start entering some form data. If a user is happy with his/her input, he/she can save that form to the server. This is a very similar problem to a shopping cart application that does not require login until checkout time.
For the authenticated user, implementing a save button is trivial. However for the anonymous user, the form data need to be stored somewhere while authentication is taking place, then correctly retrieved after logged in. Can someone please suggest some general strategies to go about this?
I found this link that is promising but I want to be thorough about this topic.
I think the correct way of doing this is to use django sessions. Basically each user (anonymousUser included) has a session during its stay on the website (or even more).
If you have a form that you want to store for a specific session, you can do it by using
request.session['myform'] = form
you get it by
request.session['myform']
and you can delete it using
del request.session['myform']
Basically Django pickles a dictionary of the session and saves it in a place (typically the database, but can be on other place as explained in django sessions).

Multiple User Types For Auth in Django

My web features two user types, Client and Professional. There are also two 'main modules', one for clients to buy stuff and so on (the main site), and the other for professionals to manage operations. For auth, I would like to have:
A single 'sign in' form, which detects whether the user is a client or a professional and forwards her to the right module (main site or management site).
Two 'sign up' forms, one for clients and other for professionals. Probably, the site will ask the user whether she wants to register as a professional or as a client, to trigger the right registration flow for each case.
Clients will use the 'main site' and should not be authorized to use the 'management site'.
Professionals will use the 'management site' but should not be authorized to sign in to the main site.
Both professionals and clients are registered as Users, and share common fields, such as username, phone, email, etc...
Since Django won't let me use two models for authentication. I've created custom model subclassing AbstractBaseUser and which serves me as a base auth class for Client and Professional.
class BaseUser(AbstractBaseUser):
...
class Client(BaseUser):
...
class Professional(BaseUser):
...
I've also changed the AUTH_USER_MODEL setting to:
AUTH_USER_MODEL = 'myapp.BaseUser'
I've also included django-allauth to manage user registration and authentication. But now I'm stuck. I just began playing with Django/Python and I'm not sure how to solve this.
It seems there is no official recommended way for doing this (Implementing multiple user types with Django 1.5). Should I stick to the subclassing approach, or should I do the OnetoOne relationship pointed out in the docs ?
Once I have the models properly setup, how should I proceed with the two registration forms? Is it possible to accomplish this with django-allauth, or do I need to do it manually?
As far as I know, when a new user is registered, a new base user is created in the User table. But since I will be creating user specializations (Client or Professional), how should I specify that I also want to create the client-related data or professional-related data in the corresponding table?
I'm pretty new to Django, so any advise will help
I think the easiest way for you to do what you are talking about is going to be to have 3 apps in your project: your top level app, a "professional" app and a "client" app. At the top level app, all you really need to do is give the users a login form, and 2 links, one for registering as a Professional and one for registering as a Client.
In this case, I believe it will be easiest for you to use Django's built in Permissions system, and assign each type of user to a corresponding group (eg. professionals and clients). You can use a decorator on your views to ensure that only members of a particular group can access that view (since you have 2 separate apps for each group, you can add a decorator to all views in each of them, or you can import Django's authorization functions into your urls.py and check it there, although that is beyond the scope of this answer).
Registration is easy enough, use your urls.py file to forward the user that wants to register to the correct app. Once you do that, you should be able to use django-allauth registration on each app, allowing you to create 2 different kinds of users. Make sure when the register, you assign them to the correct group membership.
As for the login redirection, once you receive the POST data, I would check for which type of user logged in, and use that to forward the user to the correct URL that goes with the Professional or Client app. You can see the below link for an idea of redirecting a user after login.
Django - after login, redirect user to his custom page --> mysite.com/username

Basic django app - app design issue

To learn Django, I was making a very basic app which does the following:
Takes a user's login (checks id password in a database).
If user exists and password is right, give user option to either insert,delete or update.
If insert, user can insert an entry into a common table.
Similarly for delete or update.
I was cruising through this but I just got stuck.
My Login page is /index/.
Option for insert/delete/update is at /application/.
Now next, page is displayed according to insert/delete/update at /application/action/
Now the problem is that after completing one insertion, I want to return to /application to carry on my next operation.
But if I do that, I get this error
"Key 'userid' not found in <QueryDict: {}>"
So the view for /application/ is expecting the userid and password in request.POST.
How do I get around this without using external user login modules. I just want a very basic login system just to learn.
Django comes with user authentication built in. I don't think it is external as it is included in django.contrib.
If you use the built in user authentiaction and User model, you will not have to pass the userid to each view. Django will automatically retrieve the logged in user from the session and make it available as a property of the request object.
So using built in user and authentiaction, after logging in a user, you can access that user at
request.user

Passing parameter to load data from DB after login with Django Auth App

I am new user of Django.
I want to use the built in Django Auth app for secure login. However, once a user logs in, based upon the username, I want to load it's data on the first page (lets call it welcome or home page). If I write my own login, I get stuck with URLs. All my pages become http://127.0.0.0.1:8000/login/..... I don't know where this /login/ comes from (it's written in settings file but who calls it I don't know) so after losing hope, I went for Auth login again.
I am sure there is a nice and easy way to retrieve the username but where should I write this code? in the login view of Auth app? would then that code will become part of my application?
Information about the user that's currently logged in is stored in the request.user object (request being the first parameter of every view function). request.user is an instance of the User class from django.contrib.auth. So, you can pass the user object to your templates and make all the information about the logged in user avalable that way (user.username, user.email, etc).