wev2py 1.99.2: saving sessions to database - session

In web2py version 1.99.2, at the beginning of default.py controller I wrote the following:
session.connect(request, response, db, masterapp=None)
I'm using sql server 2008 express edition. In db.py I have:
db = DAL('mssql://sa:mypass#.\SQLEXPRESS/mytest')
Now, sessions are created in the database as expected. Then in default.py controller I added:
#auth.requires_login()
def test():
return dict()
Also, default/test.html view was created. But, when I try to browse to the default/test.html page it redirects to the user/login page. The problem goes away, if I switch to the default file-based session. What's wrong with my code?

Try moving
session.connect(request, response, db, masterapp=None)
to db.py, right after you define the db connection. When auth is defined (I assume you have defined it in db.py or another model file), it needs to have access to the session, so you have to connect to the session first.

Related

Updating server side Flask sessions with AJAX not working

I'm trying to figure out why my AJAX script won't update my Flask app's server side session.
Implemented Flask-Session with sqlalchemy. I can see the table in the database and the encrypted session data.
init.py
...
from flask_session import Session
app = Flask(__name__)
app.config.from_object(Config)
db = SQLAlchemy(app)
Session(app)
...
config.py
...
SESSION_TYPE = 'sqlalchemy'
SESSION_SQLALCHEMY_TABLE = 'app_sessions'
Ajax call works as I am getting the correct response.
$.post("/ajax_fnc/_update_session", post_data)
.done(function(data) {
console.log(data)
})
Flask app returns updated cart_data:
...
#app.route('/ajax_fnc/_update_session', methods=['POST'])
def ajax_update_session():
session['cart_data']['qty'] = 1
return jsonify(session['cart_data']['qty'])
Browser console logs the updated and correct response from the Flask app. But refreshing the site loads the session with a cart data quantity of 0. So it didn't work.
How do I update the server side session with AJAX and get it to persist? What am I missing?
Note: Initializing the session with a cart quantity of 0 on the server side works just fine. Just when I attempt an update with Ajax it doesn't stick. I've spent more than half a day searching for answers but can't seem to find what I'm missing (or not understanding).
Shoot, after a lot more digging it turns out that my initialize function was being called every single time an http request was made. So... of course an ajax update would never persist.
Relocated the initialize function and the server side session works fine.

User relationships are corrupting my sessions in Symfony2

My users have a number of relationships setup in Doctrine but one in particular seems to be causing me a lot of problems, each user can have a number of memberships and each membership has a membership type.
For some reason however when I load those memberships it seems to be nuking my session, I login and get presented with a "Your Account" page as I should do but if I refresh the page I get sent back to the login screen. My sessions are stored in the database so I've been checking them to see what happens and this is what I'm seeing:
Session starts off empty
I login but make sure I get redirected to a page that doesn't load memberships
Session now contains user object and all info about relationships
I visit "Your Account" which loads memberships, they get displayed correctly.
Session has been nuked and is now as it was in step 1
I refresh the page and get sent back to the login page
I've defined my own user provider and I noticed if I set the membership type on each membership to null in refreshUser it starts working so I'm guessing the session is having trouble with that relationship.
I'm really struggling to find a solution to this so any help would be really appreciated.
EDIT: Been doing some more experimenting and found if I switch to file sessions everything starts working so it must be related to storing sessions in the database. I made the switch using the guide in the Symfony Cookbook. For reference here are the relevant bits from my config.yml:
framework:
session:
default_locale: %locale%
auto_start: true
storage_id: session.storage.pdo
parameters:
pdo.db_options:
db_table: session
db_id_col: session_id
db_data_col: session_value
db_time_col: session_time
session.storage.pdo:
class: Symfony\Component\HttpFoundation\SessionStorage\PdoSessionStorage
arguments: [#pdo, %session.storage.options%, %pdo.db_options%]
pdo:
class: PDO
arguments:
dsn: "mysql:dbname=%database_name%;host=%database_host%"
user: %database_user%
password: %database_password%
Everything else about them seems fine so maybe it's a bug in PdoSessionStorage
It might be in you equals method that is too strict. if you do $user === $otherUser; and the object have changed (the relation isnt a collection with proxies anymore) it would return false.

what happens with session_start in global.asax if session timeouts?

I have multidomain web application which treats users differently based on URL they use.
I am using Session["data"] to keep information about user and starting this session with Session_Start["data"] in Global.asax.
All works fine but I would like to know what happens after inactivity. After certain time session will timeout. If that happens is Global.asax treating this as new user and will again start Session_Start for this user?
And will Session["data"] get updated with every page load/reload? Or because it starts just once and will timeout in some exact time?
I tried to make this question as clear as possible.
Thanks.
Session will renew/keep-alive everytime the server gets hit by that user.You set the timeout in the web config file and it is a sliding value, so it restarts again everytime there is a server request.
something like this:
<configuration>
<sessionstate
mode="inproc"
cookieless="false"
timeout="20" />
</configuration>
When the session times out, the next time there is a request, the Session_Start will execute. If you are accessing Session[data] from anywhere else in the code, you should check to make sure it is not null as it will throw a NullReferenceException if the session has timed out and you are trying to access it.
A new session starts when a user first visits a .NET URL (like an .aspx page, but not a .html or other static file) on your site. That session lasts until it times out or the application is killed (restarted/crashes/recycled). The default .NET timeout is 20 minutes; so a session will last as long as the user keeps hitting .aspx pages with no breaks longer than 20 minutes.
During that time, you can store information in the Session object that relates to that user. It is essentially a hashtable that you can populate with objects for which you define keys. In your case, you are using Session["data"], but you could use any key you want, really.
However a session, and the data you store in the Session hashtable, is very fragile (see all the ways it can die above). You shouldn't rely on it to keep anything important that can't be reconstructed easily (in Session_Start, for example). So it really serves two roles: maintaining state (so you know it is still the same user from page to page); and as a user-specific cache where you can keep data in memory to do things more quickly.
Session_Start just runs once per session--by definition. If you need to identify a single user over multiple sessions, you will need to use something more permanent like setting your own cookie with a far-future expiration. You can put an ID in such a cookie that lets you know this is user 12345 (in fact, Session_Start is just the place to look for your "permanent" cookie and connect your data about that existing user with this new session).
And if you want to store data about a user that survives multiple sessions, you will have to store that somewhere more permanent--a database being the most obvious solution. When they come back, you can cache some of that data in the Session hashtable--and Session_Start is just the place to do that as well. Hope this helps.
protected void Session_Start(object sender, EventArgs e)
{
// Code that runs when a new session is started
string RootURL = Request.ApplicationPath;
if (!RootURL.EndsWith("/"))
RootURL += "/";
Globals._rootURL = RootURL;
}

Zend framework - Where to Initialize session when the router needs access to it

I work in a project which uses the session a lot. We have a db handler (the standard one from Zend) and currently i have this initialization (db handler + session start) in a plugin for the preDispatchLoop. Previously it was in preDispatch but because of it being called for each action (included those in the 'forwarded' action, it caused me problems.
My problem is that i began working in internationalization and i began using the router to detect the language in the URI: we use the form /language/controller/action). The router would like to use the session to read/store the language. But as you may know the router comes first and then the (pre/post) dispatcher stuff.
So the question would be: why not move the session initialization to the bootstrapping ? it's because it was there before but i had to move it because i need to test that the db (remember that the session uses the db) is accessible to prevent errors. And if there's an error i simply redirect (request->setController/setAction error). If i move back the session initialization code to the bootstrapping i can't make the redirect if the db is not accessible.
I've read other question and i've found many people asking to access the request object from the bootstrapping. But they all say: you can but shouldn't. but then, how would i do in this case ? my last option would be to move back the sessions initialization to the bootstrapping and if it fails, manually send headers and read the view but the error code but that's a horrible hack.
My thoughts are that the session shouldn't be used that early. They shouldn't be called in the bootstrapping as they're not yet fully aware of the controller/action requested. I think that to get the language i could simply rely in cookies (manual) and get it from there (as well as from the URI). And if eventually some day the session info must be used in the bootstrapping i would use a global variable.
What do you think ? is there an error in the way i'm controlling the application ?
Some questions seen:
Zend Framework: Getting request object in bootstrap
Best way to deal with session handling in Zend Framework
(Zend version 1.9.6, not using Application nor Bootstrap)
I would move the session initialization and db connection to the bootstrapping.
If you can't connect to your db during bootstrapp this should count as low-level error. It is not excepted to happen in production.
Simply wrap your bootstrapping process into a try catch block so you can output an error page.
// in your index.php
try {
$application = new Zend_Application(
APPLICATION_ENV,
APPLICATION_PATH . '/configs/application.ini'
);
$application->bootstrap()
->run();
} catch (Exception $e) {
header('Content-type: text/html; charset=utf-8');
header('HTTP/1.1 503 Service Unavailable');
header("Retry-After: 3600");
// Output some error page.
echo "<html><head><title>System Error</title></head><body>...</bod></html>";
?>

Manually start session with specific id / transitioning session cookie between domains

My host requires me to use a different domain for SSL secured access (shared SSL), so I need to transition the user session between two domains. One part of the page lives at http://example.com, while the SSL'd part is at https://example.hosting.com. As such I can't set a domain-spanning cookie.
What I'm trying to do is to transition the session id over and re-set the cookie like this:
http://example.com/normal/page, user clicks link to secure area and goes to:
http://example.com/secure/page, which causes a redirect to:
https://example.hosting.com/secure/page?sess=ikub..., which resurrects the session and sets a new cookie valid for the domain, then redirects to:
https://example.hosting.com/secure/page
This works up to the point where the session should be resurrected. I'm doing:
function beforeFilter() {
...
$this->Session->id($_GET['sess']);
$this->Session->activate();
...
}
As far as I can tell this should start the session with the given ID. It actually generates a new session ID though and this session is empty, the data is not restored.
This is on CakePHP 1.2.4. Do I need to do something else, or is there a better way to do what I'm trying to do?
When Configure::write('Security.level') is set to medium or higher, session.referer_check is implicitly activated, which makes the whole thing fail. Setting the security level to low (or using a custom session configuration) makes everything work as it should.
There went about 5 hours of debugging... ( -_-;;)
My first thought is to use the Cake file sessions and copy the file over, and then perhaps try and start a new session with that phpsessid, although I'm not even sure if that would actually work or not :)
With Cake 2.6.1 -- This is what worked for me.
$this->Session->id("tfvjv43hjmsnjkh0v3ss539uq7"); // add session id you want to set
$this->Session->id();
$this->Session->read("key"); // hhoorray worked :)
with SessionComponent id() function needs to be called twice once with session id to set session_id(); and second time to start cake session.
First call does not really start the session ... I dont know how Cake Guys missed it .....
Upvote if this works for you.

Resources