Ela*_*ayA 4 python oauth-2.0 google-api-python-client gmail-api google-developers-console
你好,我正在尝试将 Google Sign In 集成到我的 python 脚本中,并且运行此错误:
\n访问被阻止:此应用程序\xe2\x80\x99s请求无效
\n您无法\xe2\x80\x99 登录,因为此应用发送了无效请求。您可以稍后再试,或者联系开发人员解决此问题。了解有关此错误的更多信息
\n如果您是此应用程序的开发人员,请参阅错误详细信息。
\n错误 400:redirect_uri_mismatch
\n我尝试运行的 python 脚本是来自 Google 来源的基本脚本:
\n# import the required libraries\nfrom googleapiclient.discovery import build\nfrom google_auth_oauthlib.flow import InstalledAppFlow\nfrom google.auth.transport.requests import Request\nimport pickle\nimport os.path\nimport base64\nimport email\nfrom bs4 import BeautifulSoup\n\n# Define the SCOPES. If modifying it, delete the token.pickle file.\nSCOPES = ['https://www.googleapis.com/auth/gmail.readonly']\n\ndef getEmails():\n # Variable creds will store the user access token.\n # If no valid token found, we will create one.\n creds = None\n\n # The file token.pickle contains the user access token.\n # Check if it exists\n if os.path.exists('token.pickle'):\n\n # Read the token from the file and store it in the variable creds\n with open('token.pickle', 'rb') as token:\n creds = pickle.load(token)\n\n # If credentials are not available or are invalid, ask the user to log in.\n if not creds or not creds.valid:\n if creds and creds.expired and creds.refresh_token:\n creds.refresh(Request())\n else:\n flow = InstalledAppFlow.from_client_secrets_file('credentials.json', SCOPES)\n creds = flow.run_local_server(port=0)\n\n # Save the access token in token.pickle file for the next run\n with open('token.pickle', 'wb') as token:\n pickle.dump(creds, token)\n\n # Connect to the Gmail API\n service = build('gmail', 'v1', credentials=creds)\n\n # request a list of all the messages\n result = service.users().messages().list(userId='me').execute()\n\n # We can also pass maxResults to get any number of emails. Like this:\n # result = service.users().messages().list(maxResults=200, userId='me').execute()\n messages = result.get('messages')\n\n # messages is a list of dictionaries where each dictionary contains a message id.\n\n # iterate through all the messages\n for msg in messages:\n # Get the message from its id\n txt = service.users().messages().get(userId='me', id=msg['id']).execute()\n\n # Use try-except to avoid any Errors\n try:\n # Get value of 'payload' from dictionary 'txt'\n payload = txt['payload']\n headers = payload['headers']\n\n # Look for Subject and Sender Email in the headers\n for d in headers:\n if d['name'] == 'Subject':\n subject = d['value']\n if d['name'] == 'From':\n sender = d['value']\n\n # The Body of the message is in Encrypted format. So, we have to decode it.\n # Get the data and decode it with base 64 decoder.\n parts = payload.get('parts')[0]\n data = parts['body']['data']\n data = data.replace("-","+").replace("_","/")\n decoded_data = base64.b64decode(data)\n\n # Now, the data obtained is in lxml. So, we will parse\n # it with BeautifulSoup library\n soup = BeautifulSoup(decoded_data , "lxml")\n body = soup.body()\n\n # Printing the subject, sender's email and message\n print("Subject: ", subject)\n print("From: ", sender)\n print("Message: ", body)\n print('\\n')\n except:\n pass\n\n\ngetEmails()\n
Run Code Online (Sandbox Code Playgroud)\n我在 Google Console 中创建了一个项目,并为其提供了我的 http://localhost:8000/ 的重定向 uri
\n如果有人知道如何解决它,我会很高兴
\n谢谢。
重定向 uri 未命中匹配是我们在开始使用 Oauth2 进行开发时遇到的最常见错误之一。这实际上是您的配置错误。
错误消息上有一个链接,您可以单击该链接error details
。
在此页面上,它将告诉您应用程序发送的重定向 uri。
您需要获取该 uri 并将其添加到客户端下项目的 Google 云控制台中。
该视频还将向您展示如何
Google OAuth2:如何修复redirect_uri_mismatch 错误。第 2 部分 服务器端 Web 应用程序。
您现在拥有的代码旨在作为已安装的应用程序运行。因此,flow = InstalledAppFlow.from_client_secrets_file( CREDENTIALS, SCOPES)
它会在运行代码的计算机上打开授权同意屏幕。为了使此代码正常工作,您应该在谷歌开发者控制台上创建桌面凭据。如果您看到重定向 uri 未匹配错误,可能是因为您已经创建了 Web 应用程序凭据。
此代码并不意味着在 Web 服务器上运行,因为它会生成本地 Web 服务器。 creds = flow.run_local_server(port=0)
如果您打算在 Web 服务器 Web 服务器流上运行它,则需要不同的代码。
我仍在玩这个,我需要弄清楚如何让它根据需要刷新访问令牌。应该通过以下方式完成。我只需要弄清楚如何测试何时需要刷新。
oauth2_client = oauth2.GoogleRefreshTokenClient(
client_id, client_secret, refresh_token)
Run Code Online (Sandbox Code Playgroud)
到目前为止我所拥有的:
import os
import flask
from flask import Flask,redirect,render_template,url_for, request
app = Flask(__name__, template_folder='templates')
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 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')
return authorization_url, state
@app.route('/login')
def login():
authorization_url, state = redirect_user()
return flask.redirect(authorization_url)
@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
# Connect to the Gmail API
service = build('gmail', 'v1', credentials=credentials)
# request a list of all the messages
result = service.users().messages().list(userId='me').execute()
messages = result.get('messages')
for msg in messages:
print(msg['id'])
# saving the credetials for later.
with open('token.json', 'w') as token:
token.write(credentials.to_json())
return "", 201
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)
Run Code Online (Sandbox Code Playgroud)
归档时间: |
|
查看次数: |
5503 次 |
最近记录: |