Django: Strategies for tracking and displaying users data - python

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.

Related

Flask-restful API user accounts. Get full data and access to modify it if owner of account, get partial data otherwise

this is my first attempt to create a RESTful app using Flask framework. This is an API for cooking recipes. I already have basic functionality but I have encountered a problem with user accounts and content based on "logged in" user (username from authorization).
I run through many tutorials and documentations, but I have not found a solution I'm looking for. Only user/role based authentication to give or deny access to specified resource.
Simply: Everyone registered can see all users and their data, but only owner of the account can access full data and modify/delete it.
I've decided to use #auth.login_required decorator to check if user is registered and then in other methods (GET, POST etc.) use my own function to compare username from URL with username from auth header:
def is_owner(username):
if username == request.authorization.username:
return True
else:
return False
but I don't think this is a proper way of doing this. In POST, PUT, DELETE methods this is quite simple, because I either give or deny access, but in GET methods I want to return only part of information, so e.g. only username to guests, and full data containing email etc. for owner of the account. Same applies to other GET methods (return all recipes to owner or only those marked as public). This generates a problem with response because I would have to create new fields for each type of response in order to use marshal
The whole source code of this application is on my github.
This is mostly related question I've found, but I wonder if there are better ways.
There are for sure many bugs and strange ways in which I do some things as this is my first try. If you have some comments not regarding this particular question please let me know in comments or on my github page.

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.

How flexible is Pyramids auth system?

I am getting my feet wet working with the Pyramid framework (great framework), and I've come to the point of user authorization. I want to take advantage of the ACL to block users who are already logged in from visiting the registration page. Obviously, I could do this other ways, but I was wondering if there was any way to do this using tools in pyramid.
I know that by adding permissions to a view, users who do not meet the criteria are shown a forbidden view. In my case, I simply want to re route users who are already members away from views that don't apply to them (registration, login, etc.).
I've tried __acl__ = [(Deny, Authenticated, 'guest')] to no avail, as it blocks the login page for all users.
Also, somewhat on another note, is there any way to dynamically change a route. I want the home page to be different for users who are logged in than it is for guests.
You'll want to investigate the principals that are being returned by your authentication policy to understand what's going on. It's easy to tell if you turn on pyramid.debug_authorization in your INI file. The authorization policy will compare the ACL found against the principals returned via pyramid.security.effective_principals(request). If these do not match up, it should be clear what is going on.
The way to implement a form-based login would be (assuming Pyramid 1.3a9+):
from pyramid.httpexceptions import HTTPSeeOther
from pyramid.security import authenticated_userid
from pyramid.view import forbidden_view_config
#forbidden_view_config()
def forbidden_view(request):
if authenticated_userid(request):
# user is already logged in, they are really forbidden
return request.context # the forbidden 403 response
url = request.route_url('login', _query={'came_from': request.path})
return HTTPSeeOther(url)
That will add the came_from parameter to the URL as request.GET['came_from'] in your login view. Of course if that isn't there you can just redirect them to the home screen after logging in.

Using Python Pylons, what is a good way to use an authentication cookie throughout an application?

I'm using Python + Pylons to authenticate a user, and am then sending a unique md5 sum and storing it as a cookie to verify the user at every page load. Where in my application is the best place to put the cookie handling functions so that they are accessible throughout my application? Should I declare a global variable such as, USER, that would be accessible throughout the application storing important values like first name, last name, etc ... of the logged in user? Thanks.
It sounds like you've already got the userid in a cookie, you just want to make it more accessible. You'll probably find it useful to have a simple helper function that takes the request and returns the user.
def get_user(request):
""" Load the user from the request, or None if unauthenticated."""
if not hasattr(request, '_cookie_user'):
# parse the userid from the cookie
# make sure you actually trust this cookie by signing it
# or storing it in something that's already protected
# like beaker instead of a raw cookie
userid = request.cookies['mycookie']
request._cookie_user = DBSession.query(User).get(userid)
if user and user.is_active:
request._cookie_user = user
return getattr(request, '_cookie_user', None)
Later in your app you can simply call user = get_user(request).
A database or memcache is usually the place to store this kind of information.
Pylons provides Beaker: http://docs.pylonsproject.org/projects/pylons-webframework/en/latest/sessions.html

Auth-System easy way to do it like Amazon?

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.

Categories