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

Jon*_*n G 3 python session google-app-engine 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)
Run Code Online (Sandbox Code Playgroud)

session['credentials'] = credentials
Run Code Online (Sandbox Code Playgroud)

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

TypeError: <oauth2client.client.OAuth2Credentials object at 0x7f6c3c953610> is not JSON serializable
Run Code Online (Sandbox Code Playgroud)

正如本期(标记为WontFix)中所讨论的,OAuth2Credentials不是由JSON可序列化设计的.它有方法to_jsonfrom_json,这可以用来存储,例如:

session['credentials'] = credentials.to_json()
Run Code Online (Sandbox Code Playgroud)

但是,在同一个问题中:

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

也许我误解了Flask会话对象的工作原理,但是从doc:

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

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

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

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

Mar*_*ers 9

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

在会话中存储访问令牌:

session['credentials'] = credentials.access_token
Run Code Online (Sandbox Code Playgroud)

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

credentials = AccessTokenCredentials(session['credentials'], 'user-agent-value')
Run Code Online (Sandbox Code Playgroud)

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

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