2

所以我正在从谷歌云 shell 运行我的 Flask 应用程序。在这个应用程序中,用户需要使用他们的谷歌帐户登录。我使用云外壳安装了所有必需的库。

当我在云外壳中运行应用程序时,在选择我要登录我的应用程序的谷歌帐户后,出现此错误

flask_oauth.OAuthException
OAuthException: Invalid response from google

如果我从本地主机运行它,一切正常。

任何形式的帮助都将受到高度赞赏。

PS:这是代码

烧瓶.py:

import logging
from flask import Flask, render_template, redirect, url_for, session, make_response
from flask_oauth import OAuth
from urllib2 import Request, urlopen, URLError
import MySQLdb
import os
import json

Client_Id = my client id
Client_Secret = my client secret
Redirect_URI = '/callback'

SECRET_KEY = 'funny cat'
DEBUG = True

app = Flask(__name__)
app.debug = DEBUG
app.secret_key = SECRET_KEY
oauth = OAuth()

google = oauth.remote_app('google', base_url='https://www.google.com/accounts/', authorize_url='https://accounts.google.com/o/oauth2/auth', request_token_url=None, request_token_params={'scope': 'https://www.googleapis.com/auth/userinfo.profile', 'response_type': 'code'}, access_token_url='https://accounts.google.com/o/oauth2/token', access_token_method='POST', access_token_params={'grant_type': 'authorization_code'}, consumer_key=Client_Id, consumer_secret=Client_Secret)

@app.route('/')
def index():
    return render_template("webpage1.html")                  

@app.route('/login',methods=['post','get'])
def login():
    access_token = session.get('access_token')
    if access_token is None:
        return redirect(url_for('direct'))

    access_token = access_token[0]
    headers = {'Authorization': 'OAuth '+access_token}
    req = Request('https://www.googleapis.com/oauth2/v1/userinfo',
                  None, headers)
    try:
        res = urlopen(req)
    except URLError, e:
        if e.code == 401:
            session.pop('access_token', None)
            return redirect(url_for('direct'))
        return res.read()
    data = json.load(res)
    return render_template("webpage2.html", data = data)

@app.route('/direct')
def direct():
    callback=url_for('authorized', _external=True)
    return google.authorize(callback=callback)

@app.route(Redirect_URI)
@google.authorized_handler
def authorized(resp):
    access_token = resp['access_token']
    session['access_token'] = access_token, ''
    return redirect(url_for('login'))

@app.route('/logout')
def logout():
    session.pop('access_token', None)
    return redirect(url_for('index'))

@google.tokengetter
def get_access_token():
    return session.get('access_token')

if __name__ == "__main__":
    app.run(host='0.0.0.0', debug=True)

我在 API 中的凭据是

Authorized JavaScript origins : https://5000-dot-4778310-dot-devshell.appspot.com   
Authorized redirect URIs : https://5000-dot-4778310-dot-devshell.appspot.com/callback   

为什么相同的客户端 ID 和客户端密码的项目名称不同?

4

1 回答 1

2

这个问题实际上是如何使用在 Google Cloud Shell VM 中运行的 Flask / Python 设置 Google OAuth 2.0。

Google OAuth 2.0 授权有两种模式:localhost 模式和回调模式。

本地主机模式

这要求整个身份验证过程在具有本地运行的 Web 服务器的同一台机器上执行。连接到 Google Domain 的网络浏览器也必须在同一台机器上运行。浏览器不能在不同的机器(或 VM)上运行。由于 Cloud Shell 没有网络浏览器,因此无法使用此模式。

回调模式

这要求 Web 服务器在配置了 TLS 的情况下运行。Google OAuth 2.0 仅支持到 HTTPS 端点的回调 url。这还需要经过验证的域名和 SSL 证书。由于您既无法控制 Cloud Shell 域名,也没有证书的私钥,因此无法设置 TLS。

因此,这个问题的答案是无法设置在 Cloud Shell 中运行的服务器进程来处理 Google OAuth 2.0 身份验证。

在这个用户的案例中,回调 URL 与他的 Flask Web 服务器的配置方式不匹配。在这种情况下,无法正确配置回调 URL。

于 2018-11-18T08:54:48.777 回答