Google+登录 - 服务器端流程 - 存储凭据 - Python示例

时间:2014-04-07 14:34:29

标签: python google-app-engine session flask google-plus

我正在使用Flask在Google App Engine上构建应用。我正在使用Python示例中描述的服务器端流程实施Google+登录:https://developers.google.com/+/web/signin/server-side-flowhttps://github.com/googleplus/gplus-quickstart-python/blob/master/signin.py

两个例子都有:

credentials = oauth_flow.step2_exchange(code)

session['credentials'] = credentials

将凭证对象存储到Flask会话中。当我在我的Google App Engine项目上运行此代码时,出现错误:

TypeError: <oauth2client.client.OAuth2Credentials object at 0x7f6c3c953610> is not JSON serializable

正如this issue(标记为WontFix)中所讨论的,OAuth2Credentials并非由JSON可序列化设计。它有方法to_jsonfrom_json,可用于存储它,例如:

session['credentials'] = credentials.to_json()

然而,在same issue

  

永远不要在Cookie中存储Credentials对象,它包含应用程序
  客户端ID和客户端密码。

也许我误解了Flask会话对象的工作方式,但是来自the doc

  

...会话基本上可以记住从一个请求到另一个请求的信息。 Flask的做法是使用签名cookie。因此,用户可以查看会话内容,但不能修改它,除非他们知道密钥......

因此,我们不应该在会话中存储凭证对象,即使它是签名的cookie。

在我的情况下,我目前只需要重新使用访问令牌进行断开连接,因此我可以存储它。

处理这种情况的正确方法是什么?凭证是否应该存储在会话中?在这个例子中,是否应该发表评论“在这里安全地保存凭证”?

2 个答案:

答案 0 :(得分:9)

Flask 使用使用pickle代替JSON在会话中存储值,而Google示例代码就是为此而编写的。 Flask切换到基于JSON的格式,以减少被披露的服务器端秘密的影响(黑客可以使用pickle而不是使用JSON来劫持您的流程。

在会话中存储 访问令牌:

session['credentials'] = credentials.access_token

如果您需要,可以使用AccessTokenCredentials class稍后再次使用该令牌重新创建credentials对象:

credentials = AccessTokenCredentials(session['credentials'], 'user-agent-value')

AccessTokenCredentials对象存储凭据;因为它缺少客户端ID和客户端密钥,所以它不能用于刷新令牌。

用户代理价值是你可以弥补的;如果您有权访问OAuth服务器日志,它可以帮助诊断问题;与谷歌我不会指望,所以只是在这里做点什么。

答案 1 :(得分:-1)

“Flask默认使用Werkzeug提供的'安全cookie'作为会话系统。它通过挑选会话数据,压缩它和base64编码来工作。” - http://flask.pocoo.org/snippets/51/

换句话说,烧瓶真的很奇怪。您放入会话中的任何内容,都会使用服务器密钥进行加密,发送到客户端并存储在客户端中。然后,服务器在每个后续请求上接收它,并使用相同的密钥对其进行解码。这也意味着会话数据将在服务器重新启动后继续存在,因为它位于客户端。

为了改善我的应用程序,我使用了带有Couchdb的烧瓶SessionInterface - 现在客户端只知道对我的数据库检查的sessionID,其中存储了实际数据。乌拉。

检查一下,根据您使用的数据库,它有一些服务器端会话的方法 - http://flask.pocoo.org/snippets/category/sessions/