Google OAuth不会让我设置redirect_uri

kkih6yb8  于 2023-10-15  发布在  Go
关注(0)|答案(1)|浏览(143)

我正在尝试创建一个python应用程序来将电子邮件附件(gmail)添加到google drive。我使用了来自Youtuber Jie Jenn的代码作为基础,但遇到了redirect_uri的问题。我还尝试了其他代码示例,它们都遭遇了同样的命运
背景:我的工作场所即将进入工业行动,我们有400多名工人。我们已经设立了一个战斗基金来补偿那些因工业行动而被克扣工资的人。为了让这件事有效地发生,我已经建立了一个gmail帐户,他们可以通过电子邮件发送他们的工资单。然而,这可能会让人难以置信的艰巨去通过所有的附件每个发薪日。为了减轻负担,我想把每个月的工资单放在一个目录里。从这里,我可能可以做其他事情,如刮pdf的金额停靠。根据我有多少时间,我将添加功能,因为我去。我们周一就申请劳工行动,所以我快没时间了。否则我会一直沿着前行,直到问题得到解决。我不是一个有经验的程序员,只是一个不断学习的人,我发现坐下来学习新技能是很放松的。
问题:所以我登录到谷歌云 Jmeter 板并创建了一个项目。已创建类型为“OAuth客户端ID”的凭据。它的类型是“Web应用程序”,我已经设置了一个授权重定向URI到http://domain.i.registered.last.night域A记录指向我租用的Linux服务器,它通过我的ISP DNS解析得很好,并通过我尝试过的各种在线DNS服务。我有credentials.json或client-secrets.json,这取决于我试图使用的代码位(我已经尝试运行了几个示例),它明确地说在那里“redirect_uris”:[“http://domain.i.registered.last.night”]
然而,在我尝试过的所有示例中,当我运行代码时,我偶然发现了以下消息:请访问此URL以授权此应用程序:https://accounts.google.com/o/oauth2/auth?response_type=code&client_id=(removed).apps.googleusercontent.com&redirect_uri=http%3A%2F%2Flocalhost%3A51159%2F&scope=https%3A%2F%2Fwww.googleapis.com%2Fauth%2Fgmail.readonly+https%3A%2F%2Fwww.googleapis.com%2Fauth%2Fgmail.modify&state=(removed)&access_type=offline
如果我将该链接复制/粘贴到我的浏览器中,我会收到一个redirect_uri_mismatch错误,这显然是因为“localhost”没有设置为google dashboard上我的应用程序权限中的redirect_uri。我不确定在这个阶段是什么库产生了这个链接,但我认为它应该使用json文件来设置重定向,如果它与谷歌应用程序权限中设置的不一样,OAuth就会失败(就像这里一样)。
有人能帮忙吗?谢谢

vvppvyoh

vvppvyoh1#

您需要了解Web应用程序和已安装的应用程序之间存在差异。已安装的应用程序将在用户使用它的计算机上运行。同意屏幕在该机器上打开。Web应用程序需要在用户浏览器而不是Web服务器上打开同意屏幕。这些类型的客户端是不同的安装应用程序不需要有一个重定向URI它总是127.0.0.1,一个Web应用程序需要允许您包括重定向URI到您的网站。因此,这两种类型的客户端的代码是不同的。您正在跟踪的示例是针对已安装的应用程序的,它不会在托管中工作。
下面是我使用flask进行web auth的基本示例。

# https://github.com/googleads/googleads-python-lib/wiki/API-access-on-behalf-of-your-clients-%28web-flow%29
import os

import flask
from flask import Flask,redirect,render_template,url_for, request
app = Flask(__name__, template_folder='templates')
import google.auth.exceptions
import google_auth_oauthlib.flow
import ssl
context = ssl.SSLContext()
context.load_cert_chain('C:\Development\FreeLance\GoogleSamples\Python\cert.pem', 'C:\Development\FreeLance\GoogleSamples\Python\key.pem')
from google.oauth2.credentials import Credentials
from google.auth.transport.requests import Request
from googleapiclient.errors import HttpError
from googleapiclient.discovery import build
import google_auth_oauthlib.flow

SCOPES = ['https://mail.google.com/']

REDIRECT_URI = 'https://127.0.0.1:5000/oauth2callback'

CREDENTIALS = 'C:\Development\FreeLance\GoogleSamples\Credentials\CredWebEverything.json'

def get_flow():

    # Initialize the flow using the client ID and secret downloaded earlier.
    flow = google_auth_oauthlib.flow.Flow.from_client_secrets_file(
        CREDENTIALS,
        scopes= SCOPES,
    )
    # Indicate where the API server will redirect the user after the user completes
    # the authorization flow. The redirect URI is required.
    flow.redirect_uri = REDIRECT_URI

    return flow

def redirect_user():

    flow = get_flow()
    # Generate URL for request to Google's OAuth 2.0 server.
    # Use kwargs to set optional request parameters.
    authorization_url, state = flow.authorization_url(
        # Enable offline access so that you can refresh an access token without
        # re-prompting the user for permission. Recommended for web server apps.
        access_type='offline',
        # Enable incremental authorization. Recommended as a best practice.
        include_granted_scopes='false',
        # Forces a new refresh token when we authorize the application a second time.
        #prompt= "consent"
        )

    return authorization_url, state

@app.route('/login')
def login():
    authorization_url, state = redirect_user()
    return flask.redirect(authorization_url)

@app.route('/listmessages')
def gmail_list_messages():
    creds = None
    # The file token.json stores the user's access and refresh tokens, and is
    # created automatically when the authorization flow completes for the first
    # time.
    if os.path.exists('token.json'):
        try:
            creds = Credentials.from_authorized_user_file('token.json', SCOPES)
            print(f'Credentials exist refreshing.')
            creds.refresh(Request())
        except google.auth.exceptions.RefreshError as error:
            # if refresh token fails, reset creds to none.
            creds = None
            print(f'An error occurred: {error}')
    # If there are no (valid) credentials available, let the user log in.
    if not creds or not creds.valid:
        if creds and creds.expired and creds.refresh_token:
            creds.refresh(Request())
        else:
            # If it's not logged in then it's going to force it to.
            authorization_url, state = redirect_user()
            print(f'Credentials do not exist requesting authorization.')
            return flask.redirect(authorization_url)
    try:
        service = build('gmail', 'v1', credentials=creds)

        # Call the Gmail v1 API
        results = service.users().messages().list(
            userId='me').execute()
        messages = results.get('messages', [])
    except HttpError as error:
        # TODO(developer) - Handle errors from gmail API.
        print(f'An error occurred: {error}')

    return render_template("mail.html", data=messages)


@app.route('/')
def index():
    return render_template('index.html', title="Home Page")

@app.route('/oauth2callback')
def oauth2callback():
    flow = get_flow()

    auth_code = request.args['code']
    flow.fetch_token(code=auth_code)
    credentials = flow.credentials

    # saving the credentials for later. Note: A refresh does not return a new refresh token.
    if not os.path.exists('token.json') or credentials.refresh_token:
        print(f'Storing credentials: {credentials.to_json()}')
        with open('token.json', 'w') as token:
            token.write(credentials.to_json())

    return redirect("/listmessages")

if __name__ == '__main__':
    # Bind to PORT if defined, otherwise default to 5000.
    port = int(os.environ.get('PORT', 5000))
    app.run(host='0.0.0.0', port=port, ssl_context=context)

相关问题