I'm trying to mimic the login page from the example http://tipfy-auth.appspot.com (source http://code.google.com/p/tipfy/source/browse/examples/auth/app/) without success. I seem to run in to problem when the user is redirected back to the page. The current request flow looks like:
LoginPage (LoginHandler
) -> Facebook redirect (FacebookAuthHandler
) 302 -> Facebook.com -> Facebook redirect (FacebookAuthHandler
) 302 -> SignupPage (SignupHandler
) 302 -> LoginPage(LoginHandler
).
The problem here (as far as I figured) is the last 302(http-redirect) from signup (should be endpoint) to the loginpage again.
After some intense logging (can't find away to test this locally) it seems that a session is set when returning from facebook. The session is stored as a dict on the request handler (FacebookAuthHandler
) in two places self.auth.session
(a dict) and self.session
(a SecureCookieSession
) but after the redirect to SignupPage the self.auth.session
is None.
The redirect from SignUpPage to LoginPage occurs due to that the SignupHandler
's get method has a decorator @login_required
that looks at self.auth.session
to determine if the reuquest should be handled here or be redirected.
So why aren't the self.auth.session preserved between requests while the self.session are? Are self.auth.session
set at every request? How are the sessions stored? If it's in the db, does the datastore type matter (master/slave or high replication).
I'm digging around the source code but can't find any thing helpful.
..fredrik
EDIT
Posted answer below.
I've narrowed it down to that the problem lies within session property of the SessionAuthStore class.
When accessing the session property (this is the property @login_required looks at to determine if redirect the user or not) it runs this code (in tipfy.auth.SessionAuthStore):
if not self.loaded:
self._load_session_and_user()
return self._session
The problem here is that in the _load_session_and_user method expects to be able to a load a user from the datastore based on the 'token' key inside the session.
Unfortunately there's no user when returning from Facebook. So it will fail and redirect the user to the login page.
To proceed in my project i changed the code a bit, the @login_required (tipfy.auth.init.py)
if not auth.session:
auth._load_session() # If no session try to load it from the _session_base
if not auth.session:
return handler.redirect(auth.login_url())
And a new method on MultiAuthStore class.
def _load_session(self):
self.loaded = True
session = self._session_base.get('_auth', {})
if session:
self._session = session
Probably not the best solution but it works.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With