我试图模仿示例http://tipfy-auth.appspot.com(来源http://code.google.com/p/tipfy/source/browse/examples/auth/app/)中的登录页面,但没有成功。当用户被重定向回页面时,我似乎遇到了问题。当前请求流程如下:
LoginPage(LoginHandler
) - > Facebook重定向(FacebookAuthHandler
)302 - > Facebook.com - > Facebook重定向(FacebookAuthHandler
)302 - >注册页面(SignupHandler
)302 - > LoginPage(LoginHandler
)。
这里的问题(据我所知)是从注册(应该是端点)到登录页面的最后一次302(http重定向)。
经过一些激烈的日志记录(无法找到本地测试),似乎从facebook返回时会设置一个会话。会话在请求处理程序(FacebookAuthHandler
)中存储为dict,存储在两个位置self.auth.session
(一个字典)和self.session
(一个SecureCookieSession
)但是在重定向到SignupPage之后self.auth.session
为无。
从SignUpPage重定向到LoginPage是因为SignupHandler
的get方法有一个装饰器@login_required
,它查看self.auth.session
以确定是否应该在此处理reuquest或者是重定向。
那么为什么self.session.session不是在self.session之间的请求之间保留的?每个请求都设置self.auth.session
吗?如何存储会话?如果它在数据库中,则数据存储区类型是否重要(主/从或高复制)。
我正在挖掘源代码,但找不到任何有用的东西。
..弗雷德里克
修改
在下面发表答案。
答案 0 :(得分:1)
我已将其范围缩小到问题在于SessionAuthStore类的session属性。
当访问会话属性时(这是@login_required查看以确定是否重定向用户的属性),它运行此代码(在tipfy.auth.SessionAuthStore中):
if not self.loaded:
self._load_session_and_user()
return self._session
这里的问题是_load_session_and_user方法希望能够根据会话中的'token'键从数据存储区加载用户。
不幸的是,从Facebook返回时没有用户。因此它将失败并将用户重定向到登录页面。
要继续我的项目,我稍微更改了代码,@ logininquired(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())
MultiAuthStore类的新方法。
def _load_session(self):
self.loaded = True
session = self._session_base.get('_auth', {})
if session:
self._session = session
可能不是最好的解决方案,但它有效。