Auth-System easy way to do it like Amazon? - python

is there an easy way to configure the authentication system in Django like amazon
does it?
If you are going to login in your amazon-account and the you are going to close your browser, even after two days when you are going on the webpage again, amazon is greeting you with your name. When you are going to shop, you still need to retype your password.
Is it possible to do it this way in Djanogo? Do I have to do something special in the settings.py?
As far as I know, I just can log in or out, even when I am going to close the browser, I am logged in again without any asking of my password.
Thanks for help!
Craphunter

See the documentation on sessions, in particular the section titled Browser-length sessions vs. persistent sessions.
They explain precisely how to achieve what you're asking: request.session.set_expiry(...).

I think most likely what Amazon does is based on time and not on whether you close the browser or not. So most likely what you should do is store in the session, the last time you saw that user. If you saw them over an hour ago, then automatically log them out (use Middleware for this).
request.session['lastseen'] = datetime.datetime.now()
Now in your middlware just be careful in logging them out, as you still need to store their id or username in the session. This is still easy to do, just read here:
http://docs.djangoproject.com/en/dev/topics/auth/#how-to-log-a-user-out
So basically what you want to do is to logout a user, then after doing so, store their id or simply their username into the session so you can retrieve it later. Doing a logout will completely clear their session, so you need to make sure to add their id or username after performing the logout() command. Then wherever you want to retrieve that data you just pull it from the session variables.
logout(request.user)
request.session['userid'] = request.user.id
Then you now have three possibilities for a user: AnonymousUser w/out saved id, AnonymousUser w/ saved id, or Authenticated User.
This way even if someone isn't logged in, you still can get their id from the session.

Related

Is there any implementation of Logging out of other browsers and devices in Flask?

I have to implement a function in my website where there can only be one login per account. So, if a user logs into one browser, the others will automatically be logged out. I am using Flask for backend. Is there any such implementation in Flask, and if not, what are some ways by which I can implement this?
I don't know of any implementation. The first thing that comes to my mind is to modify the user model. You could add a column for logged_in, which get's changed to True when the user is logged in and to False if the user logs out/ the session is dropped.
You would need to check this attribute when verifying the user login. For further specific help consider posting an MRE of your question.

Django: Strategies for tracking and displaying users data

Details
I have made my custom authentication process for the users, (no, i didn't use django's dedicated authentication), I almost finished it, but still having concerns on the most important part at the time.
so these are main parts of authentication process:
User sign's into the website via steam's social authentication.
My authentication system checks if database contains user's data, if not it will create a new user object with all the information.
System will create cookie as key logged with the value of True.
After these steps, there begins a problem, website should show users data when logged cookie's value is True.
Strategies and Questions
So as example, let's take stackoverflow, as i see: when it's login cookie is activated, it show's me my profile picture, and my score.
How did it know that i was that specific user?
via cookies:
If i tracked users data via cookies, i know that it would be a very bad idea since they are super-easy to change.
via ip address:
Then there's a second way, to track them with ip address, which i don't think is a good idea:
from .models import User, IPs
from django.http import HttpResponseRedirect, HttpResponse
import steamapi
def index(request, self):
ip = request.META['HTTP_X_FORWARDED_FOR']
for search in IPs.objects.all():
if str(ip) in str(search):
break
user = ip.strip(ip) # model will contain ip address with username. e.g ( user 127.0.0.1 ), so i strip the ip
else:
username = steamapi.user.SteamUser(self.steamid) # i get steamid from different function which is not important.
username = IPs(data=username + " " + ip)
username.save()
print request.COOKIES
if request.COOKIES.get('logged'):
return HttpResponse("User %s" + "is logged in" % username)
else:
response = HttpResponse("User is not logged in")
response.set_cookie('logged', True)
return response
via sessions:
I don't exactly know Django's sessions (except cookies), would it be good if i used django's cached sessions? if so how?
Note: i am looking for the code that will fit to my steps at beginning, so code example would be excellent.
First strategy is totally bad idea, i think second is not pythonic and is not a good strategy, Third however, is one i need a help with.
General Question:
So what would best strategy be for displaying specific users data on the website? As i mentioned simillar to stackoverflow's bar, where it displays my profile picture and score.
Writing your own auth system is a nice way to learn all the details of how it works, but you must be careful to not introduce security issues. The Django auth framework has been working for 10 years or so, so it can be trusted to do the right thing.
Bruno's answer is right: you should use sessions. Sessions work by setting a cookie with a random value on the user's computer. After that, the browser sends back that random value on each request, and the Django Session framework (a middleware, IIRC) matches the random string with a Session instance (dict like object) and puts it in the request instance.
If you're using a modern Django version and for any reason want to stick to using Cookies only, you can check out the new Cookie based sessions. Internally, it signs the cookie (meaning no-one else can tamper with it, even though it's stored on the user's computer).
The canonical solution is to use sessions. FWIW note that all of your problems are already solved in Django's contrib.auth app, taking care of a whole lot of known security issues.

Save additional info to Facebook authenticated user?

I'm using python-social-auth and I'm successfully able to authenticate a user with his Facebook account, but only the email is persisted. How do I:
persist the birthday?
add and persist information that doesn't come from FB, like his pet name? (as far as I know, I'll have to use a pipeline but don't know how)
Any help will be appreciated.
Thanks in advance!
PS: Would someone with enough reputation create a tag 'python-socialauth'?
Birthdate persistence is as simple as defining SOCIAL_AUTH_FACEBOOK_EXTRA_DATA = [('birthdate', 'birthdate')], later you can access it by doing user.social_auth.get(provider='facebook').extra_data['birthdate'].
Other data must be saved with a pipeline, which is not as simple, but not hard to do. A pipeline is a function that will be called during the auth process (even on signup, login or association, so the function needs to check for that if needed). The function will get many parameters like the strategy, backend, social, user, response, requests, details, etc, it's best to define the needed parameters and then use **kwargs to ignore the others.
Once the function is coded, it should be added to SOCIAL_AUTH_PIPELINE setting (be sure to add the default entries also, or the auth process won't work, those can be find here http://psa.matiasaguirre.net/docs/pipeline.html#authentication-pipeline).

Django User Sessions, Cookies and Timeout

I'm working with a Django application and my current goal is to keep track of the user session with cookies. I have a feeling that, as always, my understanding is a bit off with regards to how I do this.
For starters, I would like to manage how long it has been since a user has logged in, that way I can successfully log them out if they haven't visited a new page in "x" hours. I am not sure what exactly is standard (for a social network).
Is this information I store on my server? Do cookies actually have any relevancy here? I've used cookies before to store things like a user's timezone, but I am struggling to deal with how I keep track of the user.
All I currently have in terms of user back end is from the django.contrib.auth package.
The only thing I really know how to do in terms of "grabbing" the user's info is done by using statements like if request.user.is_authenticated(): (etc.).
I realize this is somewhat of a complex question, so I will try and narrow it down:
How do I extend my existing information about the current user to capture "last activity" so I can log him/her out if they haven't been using the site in a certain period of time?
Do I need to define a custom user model?
My next step after is to create a different type of user, so I feel like I need to make custom user models - beyond just extending the normal user form to make a profile etc.
Thanks for your understanding,
I know I can be confusing when I don't understand things.
Thanks for your time,
James
You can configure the session middleware for logging out the user automatically,
configure the SESSION_COOKIE_AGE, to some low value, and provide the SESSION_SAVE_EVERY_REQUEST, as True.
This will automatically logout the user after certain inactivity, without any need of extending the profile.
SESSION_COOKIE_AGE
Default: 1209600 (2 weeks, in seconds)
>> The age of session cookies, in seconds.
SESSION_SAVE_EVERY_REQUEST
Default: False
>> Whether to save the session data on every request.
If this is False (default), then the session data will only be saved if it has been modified – that is, if any of its dictionary values have been assigned or deleted.
And for creating custom/extending User Profile, Django 1.5, comes with configurable User model, please check the docs for examples.

Checking login status at every page load in CherryPy

I am in the midst of writing a web app in CherryPy. I have set it up so that it uses OpenID auth, and can successfully get user's ID/email address.
I would like to have it set so that whenever a page loads, it checks to see if the user is logged in, and if so displays some information about their login.
As I see it, the basic workflow should be like this:
Is there a userid stored in the current session? If so, we're golden.
If not, does the user have cookies with a userid and login token? If so, process them, invalidate the current token and assign a new one, and add the user information to the session. Once again, we're good.
If neither condition holds, display a "Login" link directing to my OpenID form.
Obviously, I could just include code (or a decorator) in every public page that would handle this. But that seems very... irritating.
I could also set up a default index method in each class, which would do this and then use a (page-by-page) helper method to display the rest of the content. But this seems like a nightmare when it comes to the occasional exposed method other than index.
So, my hope is this: is there a way in CherryPy to set some code to be run whenever a request is received? If so, I could use this to have it set up so that the current session always includes all the information I need.
Alternatively, is it safe to create a wrapper around the cherrypy.expose decorator, so that every exposed page also runs this code?
Or, failing either of those: I'm also open to suggestions of a different workflow. I haven't written this kind of system before, and am always open to advice.
Edit: I have included an answer below on how to accomplish what I want. However, if anybody has any workflow change suggestions, I would love the advice! Thanks all.
Nevermind, folks. Turns out that this isn't so bad to do; it is simply a matter of doing the following:
Write a function that does what I want.
Make the function in to a custom CherryPy Tool, set to the before_handler hook.
Enable that tool globally in my config.

Categories