Google API OAuth 2.0 无法验证错误 400:redirect_uri_mismatch
Google API OAuth 2.0 can't authenticate Error 400: redirect_uri_mismatch
我想创建一个对多个用户日历事件具有只读访问权限的应用程序。但是,我总是无法通过身份验证步骤。浏览器打开新的同意屏幕并显示 错误 400:redirect_uri_mismatch。这是我所做的:
为此,我在 google 控制台中设置了我的项目。我做了以下操作:
- 首先创建一个新项目,并在“APIs”页面上启用 Google 日历 API。
- 已配置同意屏幕
- 通过为应用程序类型选择 Web 应用程序和为身份验证方法选择 OAuth 2.0 创建凭据,并将“授权重定向 URI”设置为“http://localhost:8080”。现在网络应用程序在本地托管。
- 已在本地下载 credentials.json 文件。 json 文件如下:
{"web":
{
"client_id":"123234-jjjjj.apps.googleusercontent.com",
"project_id":"ppppp-1234",
"auth_uri":"https://accounts.google.com/o/oauth2/auth",
"token_uri":"https://oauth2.googleapis.com/token",
"auth_provider_x509_cert_url":"https://www.googleapis.com/oauth2/v1/certs",
"client_secret":"zzzzzzzzzzzzzzzzzz",
"redirect_uris":["http://localhost:8080"],
"javascript_origins":["http://localhost"]
}
}
我使用下面的代码调用 google API:
import pickle
import os
from google_auth_oauthlib.flow import Flow, InstalledAppFlow
from googleapiclient.discovery import build
from googleapiclient.http import MediaFileUpload
from google.auth.transport.requests import Request
def Create_Service(client_secret_file, api_name, api_version, *scopes):
CLIENT_SECRET_FILE = client_secret_file
API_SERVICE_NAME = api_name
API_VERSION = api_version
SCOPES = [scope for scope in scopes[0]]
cred = None
pickle_file = f'token_{API_SERVICE_NAME}_{API_VERSION}.pickle'
if os.path.exists(pickle_file):
with open(pickle_file, 'rb') as token:
cred = pickle.load(token)
if not cred or not cred.valid:
if cred and cred.expired and cred.refresh_token:
cred.refresh(Request())
else:
flow = InstalledAppFlow.from_client_secrets_file(CLIENT_SECRET_FILE, SCOPES)
cred = flow.run_local_server()
with open(pickle_file, 'wb') as token:
pickle.dump(cred, token)
try:
service = build(API_SERVICE_NAME, API_VERSION, credentials=cred)
print(API_SERVICE_NAME, 'service created successfully')
return service
except Exception as e:
print(e)
return None
CLIENT_SECRET_FILE = 'token.json'
API_NAME = 'calendar'
API_VERSION = 'v3'
SCOPES = ['https://www.googleapis.com/auth/calendar.events.readonly']
service = Create_Service(CLIENT_SECRET_FILE, API_NAME, API_VERSION, SCOPES)
colors = service.colors().get().execute()
print(colors)
当我 运行 它时,浏览器会打开一个同意屏幕
Error 400: redirect_uri_mismatch.
Then I follow http://localhost:8080/ and I see message "The authentication flow has completed. You may close this window."
并且在控制台中我看到以下错误:
File "main.py", line 48, in <module>
service = Create_Service(CLIENT_SECRET_FILE, API_NAME, API_VERSION, SCOPES)
File "main.py", line 29, in Create_Service
cred = flow.run_local_server()
File "/home/ev/Projects/TIM/web/.venv/lib/python3.8/site-packages/google_auth_oauthlib/flow.py", line 480, in run_local_server
self.fetch_token(authorization_response=authorization_response)
File "/home/ev/Projects/TIM/web/.venv/lib/python3.8/site-packages/google_auth_oauthlib/flow.py", line 288, in fetch_token
return self.oauth2session.fetch_token(self.client_config["token_uri"], **kwargs)
File "/home/ev/Projects/TIM/web/.venv/lib/python3.8/site-packages/requests_oauthlib/oauth2_session.py", line 239, in fetch_token
self._client.parse_request_uri_response(
File "/home/ev/Projects/TIM/web/.venv/lib/python3.8/site-packages/oauthlib/oauth2/rfc6749/clients/web_application.py", line 203, in parse_request_uri_response
response = parse_authorization_code_response(uri, state=state)
File "/home/ev/Projects/TIM/web/.venv/lib/python3.8/site-packages/oauthlib/oauth2/rfc6749/parameters.py", line 268, in parse_authorization_code_response
raise MismatchingStateError()
oauthlib.oauth2.rfc6749.errors.MismatchingStateError: (mismatching_state) CSRF Warning! State not equal in request and response.
那么,问题是如何以正确的方式通过 OAuth 2.0 向 google API 进行身份验证?
redirect_uri_mismatch
Web 应用程序使用重定向 uri 来指示您的应用程序准备接受来自 google 授权服务器的授权响应的位置。它基本上是 Web 服务器上准备响应授权的 URL。重定向 uris 仅用于 Web 应用程序。
在您的情况下,您正在创建一个已安装的应用程序 InstalledAppFlow
,在这种情况下,您应该已经在 Google 开发人员控制台上创建了已安装的(桌面)凭据。桌面客户端能够从他们发送的位置接受授权响应,这通常是本地主机,因此授权服务器只是 returns 将令牌返回到调用的来源。
由于您的代码旨在通过向其提供 Web 应用程序凭据 运行 作为已安装的应用程序,这将导致它失败,因为该应用程序未发送正确的请求。
我这里有一个视频,将向您展示如何在 google 开发者控制台上创建 How to create Google Oauth2 installed application credentials。
我想创建一个对多个用户日历事件具有只读访问权限的应用程序。但是,我总是无法通过身份验证步骤。浏览器打开新的同意屏幕并显示 错误 400:redirect_uri_mismatch。这是我所做的:
为此,我在 google 控制台中设置了我的项目。我做了以下操作:
- 首先创建一个新项目,并在“APIs”页面上启用 Google 日历 API。
- 已配置同意屏幕
- 通过为应用程序类型选择 Web 应用程序和为身份验证方法选择 OAuth 2.0 创建凭据,并将“授权重定向 URI”设置为“http://localhost:8080”。现在网络应用程序在本地托管。
- 已在本地下载 credentials.json 文件。 json 文件如下:
{"web":
{
"client_id":"123234-jjjjj.apps.googleusercontent.com",
"project_id":"ppppp-1234",
"auth_uri":"https://accounts.google.com/o/oauth2/auth",
"token_uri":"https://oauth2.googleapis.com/token",
"auth_provider_x509_cert_url":"https://www.googleapis.com/oauth2/v1/certs",
"client_secret":"zzzzzzzzzzzzzzzzzz",
"redirect_uris":["http://localhost:8080"],
"javascript_origins":["http://localhost"]
}
}
我使用下面的代码调用 google API:
import pickle
import os
from google_auth_oauthlib.flow import Flow, InstalledAppFlow
from googleapiclient.discovery import build
from googleapiclient.http import MediaFileUpload
from google.auth.transport.requests import Request
def Create_Service(client_secret_file, api_name, api_version, *scopes):
CLIENT_SECRET_FILE = client_secret_file
API_SERVICE_NAME = api_name
API_VERSION = api_version
SCOPES = [scope for scope in scopes[0]]
cred = None
pickle_file = f'token_{API_SERVICE_NAME}_{API_VERSION}.pickle'
if os.path.exists(pickle_file):
with open(pickle_file, 'rb') as token:
cred = pickle.load(token)
if not cred or not cred.valid:
if cred and cred.expired and cred.refresh_token:
cred.refresh(Request())
else:
flow = InstalledAppFlow.from_client_secrets_file(CLIENT_SECRET_FILE, SCOPES)
cred = flow.run_local_server()
with open(pickle_file, 'wb') as token:
pickle.dump(cred, token)
try:
service = build(API_SERVICE_NAME, API_VERSION, credentials=cred)
print(API_SERVICE_NAME, 'service created successfully')
return service
except Exception as e:
print(e)
return None
CLIENT_SECRET_FILE = 'token.json'
API_NAME = 'calendar'
API_VERSION = 'v3'
SCOPES = ['https://www.googleapis.com/auth/calendar.events.readonly']
service = Create_Service(CLIENT_SECRET_FILE, API_NAME, API_VERSION, SCOPES)
colors = service.colors().get().execute()
print(colors)
当我 运行 它时,浏览器会打开一个同意屏幕
Error 400: redirect_uri_mismatch. Then I follow http://localhost:8080/ and I see message "The authentication flow has completed. You may close this window."
并且在控制台中我看到以下错误:
File "main.py", line 48, in <module>
service = Create_Service(CLIENT_SECRET_FILE, API_NAME, API_VERSION, SCOPES)
File "main.py", line 29, in Create_Service
cred = flow.run_local_server()
File "/home/ev/Projects/TIM/web/.venv/lib/python3.8/site-packages/google_auth_oauthlib/flow.py", line 480, in run_local_server
self.fetch_token(authorization_response=authorization_response)
File "/home/ev/Projects/TIM/web/.venv/lib/python3.8/site-packages/google_auth_oauthlib/flow.py", line 288, in fetch_token
return self.oauth2session.fetch_token(self.client_config["token_uri"], **kwargs)
File "/home/ev/Projects/TIM/web/.venv/lib/python3.8/site-packages/requests_oauthlib/oauth2_session.py", line 239, in fetch_token
self._client.parse_request_uri_response(
File "/home/ev/Projects/TIM/web/.venv/lib/python3.8/site-packages/oauthlib/oauth2/rfc6749/clients/web_application.py", line 203, in parse_request_uri_response
response = parse_authorization_code_response(uri, state=state)
File "/home/ev/Projects/TIM/web/.venv/lib/python3.8/site-packages/oauthlib/oauth2/rfc6749/parameters.py", line 268, in parse_authorization_code_response
raise MismatchingStateError()
oauthlib.oauth2.rfc6749.errors.MismatchingStateError: (mismatching_state) CSRF Warning! State not equal in request and response.
那么,问题是如何以正确的方式通过 OAuth 2.0 向 google API 进行身份验证?
redirect_uri_mismatch
Web 应用程序使用重定向 uri 来指示您的应用程序准备接受来自 google 授权服务器的授权响应的位置。它基本上是 Web 服务器上准备响应授权的 URL。重定向 uris 仅用于 Web 应用程序。
在您的情况下,您正在创建一个已安装的应用程序 InstalledAppFlow
,在这种情况下,您应该已经在 Google 开发人员控制台上创建了已安装的(桌面)凭据。桌面客户端能够从他们发送的位置接受授权响应,这通常是本地主机,因此授权服务器只是 returns 将令牌返回到调用的来源。
由于您的代码旨在通过向其提供 Web 应用程序凭据 运行 作为已安装的应用程序,这将导致它失败,因为该应用程序未发送正确的请求。
我这里有一个视频,将向您展示如何在 google 开发者控制台上创建 How to create Google Oauth2 installed application credentials。