使用 Google+ 进行身份验证时在会话中存储 oauth 凭据时出错

Error storing oauth credentials in session when authenticating with Google+

我正在学习使用 G+ 进行身份验证的教程。我有以下路线来处理身份验证并将凭据放入 Flask 会话中。 (实际代码要长得多,一路上都有错误检查。可以在my GitHub project中找到。)

访问路由报序列化错误。我知道它正在尝试序列化它不能序列化的东西。我如何找到并修复它?

@app.route('/gconnect', methods=['POST'])
def gconnect():
    oauth_flow = flow_from_clientsecrets('client_secrets.json', scope='')
    oauth_flow.redirect_uri = 'postmessage'
    credentials = oauth_flow.step2_exchange(request.data)
    login_session['credentials'] = credentials
    login_session['gplus_id'] = credentials.id_token['sub']

    answer = requests.get('https://www.googleapis.com/oauth2/v1/userinfo', params={'access_token': credentials.access_token, 'alt': 'json'})
    data = answer.json()
    login_session['username'] = data['name']
    login_session['picture'] = data['picture']
    login_session['email'] = data['email']

    return make_response(json.dumps('Successfully connected user.', 200))
10.0.2.2 - - [12/Apr/2015 14:48:18] "POST /gconnect?state=Y8LV4CFTO00K16G09SLIZZ2CSGR3ZH32 HTTP/1.1" 500 -
Traceback (most recent call last):
  File "/usr/lib/python2.7/dist-packages/flask/app.py", line 1836, in __call__
    return self.wsgi_app(environ, start_response)
  File "/usr/lib/python2.7/dist-packages/flask/app.py", line 1820, in wsgi_app
    response = self.make_response(self.handle_exception(e))
  File "/usr/lib/python2.7/dist-packages/flask/app.py", line 1403, in handle_exception
    reraise(exc_type, exc_value, tb)
  File "/usr/lib/python2.7/dist-packages/flask/app.py", line 1817, in wsgi_app
    response = self.full_dispatch_request()
  File "/usr/lib/python2.7/dist-packages/flask/app.py", line 1479, in full_dispatch_request
    response = self.process_response(response)
  File "/usr/lib/python2.7/dist-packages/flask/app.py", line 1693, in process_response
    self.save_session(ctx.session, response)
  File "/usr/lib/python2.7/dist-packages/flask/app.py", line 837, in save_session
    return self.session_interface.save_session(self, session, response)
  File "/usr/lib/python2.7/dist-packages/flask/sessions.py", line 326, in save_session
    val = self.get_signing_serializer(app).dumps(dict(session))
  File "/usr/lib/python2.7/dist-packages/itsdangerous.py", line 537, in dumps
    payload = want_bytes(self.dump_payload(obj))
  File "/usr/lib/python2.7/dist-packages/itsdangerous.py", line 809, in dump_payload
    json = super(URLSafeSerializerMixin, self).dump_payload(obj)
  File "/usr/lib/python2.7/dist-packages/itsdangerous.py", line 522, in dump_payload
    return want_bytes(self.serializer.dumps(obj))
  File "/usr/lib/python2.7/dist-packages/flask/sessions.py", line 85, in dumps
    return json.dumps(_tag(value), separators=(',', ':'))
  File "/usr/lib/python2.7/dist-packages/flask/json.py", line 126, in dumps
    rv = _json.dumps(obj, **kwargs)
  File "/usr/lib/python2.7/dist-packages/simplejson/__init__.py", line 369, in dumps
    **kw).encode(obj)
  File "/usr/lib/python2.7/dist-packages/simplejson/encoder.py", line 262, in encode
    chunks = self.iterencode(o, _one_shot=True)
  File "/usr/lib/python2.7/dist-packages/simplejson/encoder.py", line 340, in iterencode
    return _iterencode(o, 0)
  File "/usr/lib/python2.7/dist-packages/flask/json.py", line 83, in default
    return _json.JSONEncoder.default(self, o)
  File "/usr/lib/python2.7/dist-packages/simplejson/encoder.py", line 239, in default
    raise TypeError(repr(o) + " is not JSON serializable")
TypeError: <oauth2client.client.OAuth2Credentials object at 0xb57e388c> is not JSON serializable

您正在尝试在会话中存储凭据 object,而不是实际的凭据 data。会话数据使用 JSON 序列化,因此其中的所有数据必须 JSON 可序列化。

要了解您实际需要在会话中存储什么以使用您刚刚执行的身份验证,您可以查看您对 /userinfo 的请求,您将 credentials.access_token.

访问令牌通常是您在任何 oauth 周期后需要记住的内容。不存储凭据对象,只存储访问令牌。

# remove the session['credentials'] line
login_session['access_token'] = credentials.access_token

现在您可以在其他路由的会话中使用此令牌进行其他 api 调用。

我遇到了类似的问题,并且能够通过

将凭据对象转换为 json
login_session['credentials'] = credentials.to_json()