I recently began a project to migrate our web app from apache + Mod_python to just cherry-py.
There is still a good deal of stuff I still need to do, but for now, it is CherryPy's sessions that are giving me a bit of a headache.
My first question is how do they work?
In Mod_python, we do something like this:
...
from mod_python import Session
sess = Session.Session(req, timeout = 60*60, lock=0)
#req is the request page object.
Judging from the CherryPy documentation, all I need to do to start a session is modify the config by adding something like the following:
cherrypy.config.update({
'tools.sessions.on': True,
'tools.sessions.storage_type': 'ram'})
The above defaults to a time of 60 minutes (though you can manually set your own), but what if I want to destroy that session and make a new one? Do, I call cherrypy.lib.sessions.expire() in any arbitrary file and then do the cherrypy.config.update thing again? Or, will CherryPy make a new session by itself? What if I want to make a new session with a different expiry time?
Note: When I say arbitrary file, I mean a file that is not running CherryPy (My "config" file imports and gets html back from our other pages much like the standard Publisher that comes with Mod_Python).
I tried making a quick little test file:
import cherrypy
from cherrypy.lib import sessions
def index(sid=0, secret=None, timeout=30, lock=1):
cherrypy.session['test'] = 'test'
cherrypy.lib.sessions.expire()
return cherrypy.session.get('test','None')
The end result is that 'test' is still displayed on the screen. Is this happening because the client side session is expired, but the local one still has data? In that case, how can I check if a session expired or not?
Sorry for the confusing question, but I am confused.
Thanks for all your help!
Try this to end a session.
sess = cherrypy.session
sess['_cp_username'] = None
and try this to create a session...
cherrypy.session.regenerate()
cherrypy.session['_cp_username'] = cherrypy.request.login
I used this example to handle most of my session activity.
http://tools.cherrypy.org/wiki/AuthenticationAndAccessRestrictions
Hope this helps,
Andrew
Related
So I'm going through the auth-o-matic flask tutorial. I was able to get it to work but now I want to of course apply the session to my other pages. If a user has logged in they will have a session specific to the browser. The tutorial recommended If I wanted to use flask-session to save the session in this way.
result = authomatic.login(
WerkzeugAdapter(request, response),
provider_name,
session=session,
session_saver=lambda: app.save_session(session, response)
)
When looking at examples like (runnable.com/Uhf58hcCo9RSAACs/using-sessions-in-flask-for-python) this using flask sessions I notice that the session is bound more explicitly to app.session. Which makes sense that I can then check the session in an if statement every time a user requests a route.
I imagine something like,
#app.route('/content')
def content():
if app.open_session(app):
return render_template('content.html', session=app.open_session() )
return render_template('content.html')
This makes sense to me so I'm wondering if it's coming from a misunderstanding of sessions. If anyone can explain this small example for me of explain why it doesn't work I would really appreciate it! I've posted the full code on a GitHub gist (link below).
TLDR: I have a facebook authentication from auth-o-matic and I can't access the session variable to apply it to my other routes to make sure a user is logged in when accessing critical sections. Code examples and full code in links.
Thank You!
https://gist.github.com/DavidAwad/f881a6ec64e8e2be2b86
Two questions regarding session timeouts in cherrypy:
1) Is there a way to determine the remaining time in a session? This is related to trying to use http://plugins.jquery.com/epilgrim.sessionTimeoutHandler/
2) Is there a way to make a call to cherrypy NOT reset the timeout, such that the plugin above could call a URL to determine the time remaining in the session without resetting said time
Edit to help clarify: The purpose here is to be able to have a client-side process that periodically queries the server via AJAX to determine the amount of time left in a users session. This is to overcome difficulties with keeping a client side session timeout timer in-sync with the server-side timer - I'd like to simply have the client ask the server "how much time do I have left?" and act accordingly. Of course, if the act of asking resets the timeout, then this won't work, as the AJAX "time left" requests would essentially become a session keep-alive. So I need to be able to make an AJAX query to the server without resetting the session timeout timer for the user.
I believe cherrypy uses the expiration time in the cookie with the key session_id. Mine says:
Wed 22 Jan 2014 03:44:31 PM EST
You could extend the expiration with your set of circumstances and edit the session cookie.
EDIT: You will also need to extend the server timeout...
cherrypy.request.config.update({'tools.sessions.timeout': 60})
https://groups.google.com/forum/#!topic/cherrypy-users/2yrG79QoYFQ
Hope this helps!
You need to subclass the session and add a "stats" function to it and a flag to prevent saving in the session "stats" request handler. Or disable sessions in the config for the "stats" path and load session exp info directly from your storage without using normal session class.
I have found the answer to 2) question while going through source code of cherrypy session class. Apparently, you do not want to save session after serving such requests - this will then also not update expiration time (and will not save any changes to session object).
I found in the source code that setting cherrypy.serving.request._sessionsaved = True does exactly that. And added decorator for convinience:
def nosessionsave( func ):
"""
Decorator to avoid session saving and thus not resetting session timeout.
"""
def decorate( *args, **data ):
cherrypy.serving.request._sessionsaved = True
return func( *args, **data )
return decorate
Just add #nosessionsave before method def.
I have been developing a web app using web.py. It uses a session like below:
store = web.session.DBStore(db.sess, "sessions")
session = web.session.Session(
app,
store,
initializer={
"auth": False,
"username": "anonymous",
"preferences": db.data.select('preferences', where="username='anonymous'", limit=1)[0]
}
)
web.config._session = session
I decided, it could be useful to have a desktop application as well. A problem I am running into though, is I cannot get a session to work properly outside of a web browser. I believe it's just another object that holds specific data, but I am not entirely sure.
What I need is some way to either use web.py to create a session so I can use all of my functions with it (many check for a session to see who is logged in) or I need some way to create a "fake" session containing essentially the same data as before so I could still use the functions.
My whole goal in this is to keep using the same model, since then I wouldn't have to rewrite many functions that just duplicate functionality.
I found out what I was doing wrong. Turns out web.input needs context, which is not available outside of the browser as far as I could see.
What I ended up doing was changing my login(...) method from login(input) to login(username, password). Now, from the interactive shell, I can get a session. I believe this will carry over into a desktop application as the interactive shell is not a browser.
I have been debugging this half a day now... anybody have ideas?
I wrote a python script to monitor active sessions, found this:
sessions = Session.objects.filter(expire_date__gte=datetime.now())
for session in sessions:
data = session.get_decoded()
id = data.get('_auth_user_id', None)
ses = session.session_key
if id:
name = User.objects.get(id=id)
gives nice list... ok. But -- if user logs out or in, the above code does not reflect the change. It just keeps repeating the original, outdated list.
Is there a caching issue? Think not -- disabled memcached, and no change.
Tried file and memcache based session storage -- strange result: the code above seems to read db-based session storage.
So, I suspect the initialization is not correct for the 1.4.3 -- as there seem to have been various ways to initialize environment. I believe 1.4. does not require anything but the environment variable DJANGO_SETTINGS_MODULE to be set to the app.
Next, if this does not resolve.. must use file based session storage and poll the directory.. that seems to be alive and kicking in realtime :)
Your problem is caused by transaction isolation. By default, each connection to the db runs inside a transaction. Usually, that equates to a view, and the transaction middleware takes care of opening and closing the transaction. In a standalone script, you'll need to manage that yourself.
I am working on a python web application based on the pyramid framework. I am trying to add session authentication to it. By that I understand that:
users can log in/out (security is desirable); user data are kept in a database
authentication is handled via the session (request.session)
First off: Is session authentication a good option or are there better ones?
Secondly: I can't really make heads or tails of the documentation and examples.
So far, I've followed http://docs.pylonsproject.org/projects/pyramid/en/1.3-branch/tutorials/wiki2/authorization.html#adding-login-and-logout-views so far that I have a login/logout form. However, my authn_policy is a http://docs.pylonsproject.org/projects/pyramid/en/latest/api/authentication.html#pyramid.authentication.SessionAuthenticationPolicy
As the session factory in pyramid is insecure (see http://docs.pylonsproject.org/projects/pyramid/en/1.3-branch/narr/sessions.html), I use *pyramid_beaker* instead.
The configuration is:
in __init__.py: session_factory = session_factory_from_settings(settings)
in the .ini file:
beaker.session.lock_dir = %(here)s/data/sessions/lock
beaker.session.type = ext:database
beaker.session.sa.url = mysql://user:pass#localhost:3306/db
beaker.session.table_name = user_session
I hope I was able to make my problem clear.
I'd say it depends on what you want to do. Session authentication works fine if you use Beaker, but I like using AuthTktAuthenticationPolicy for the additional timeout and reissue options, and the fact that your authentication doesn't disappear even if you clear the session.