我想做什么:
我正试图构建一个Python 3.9程序,使用OAuth2凭据(设置为“测试”发布状态,作为“web应用程序”类型和“外部”用户类型)每天调用YouTube数据API v3,每次进行唯一调用时存储刷新令牌以获得新的访问令牌
我一直在使用YouTube Data API v3 official documentation,来自Google API repository on GitHub的Python代码示例,以及我从Corey Schafer on YouTube找到的OAuth令牌解决方案
到目前为止我所尝试的:
这是我的Python代码(为了匿名起见,我对播放列表ID进行了置乱,但是如果您为一个具有凭据的频道输入自己的播放列表ID,代码运行良好):
# YouTube Data API v3
# Pulling data for the brand account
import os
import pickle
from google_auth_oauthlib.flow import InstalledAppFlow
from google.auth.transport.requests import Request
from googleapiclient.discovery import build
credentials = None
# youtube_data_token_brand.pickle stores the user's credentials from previously successful logins
if os.path.exists('youtube_data_token_brand.pickle'):
print('Loading Credentials From File...')
with open('youtube_data_token_brand.pickle', 'rb') as token:
credentials = pickle.load(token)
# If there are no valid credentials available, then either refresh the token or log in.
if not credentials or not credentials.valid:
if credentials and credentials.expired and credentials.refresh_token:
print('Refreshing Access Token...')
credentials.refresh(Request())
else:
print('Fetching New Tokens...')
flow = InstalledAppFlow.from_client_secrets_file(
'client_secrets_youtube_data_brand.json',
scopes=[
'https://www.googleapis.com/auth/youtube.readonly'
]
)
flow.run_local_server(port=8080, prompt='consent',
authorization_prompt_message='')
credentials = flow.credentials
# Save the credentials for the next run
with open('youtube_data_token_brand.pickle', 'wb') as f:
print('Saving Credentials for Future Use...')
pickle.dump(credentials, f)
youtube = build('youtube', 'v3', credentials=credentials)
request = youtube.playlistItems().list(
part="status, contentDetails", playlistId='UUlG34RnfYmCsNFgxmTmYjPA', maxResults=28
)
response = request.execute()
for item in response["items"]:
vid_id = (item["contentDetails"]["videoId"])
yt_link = f"https://youtu.be/{vid_id}"
print(yt_link)
我得到的结果:
我的程序运行了大约一周,然后我发现以下错误(同样,为了匿名,我编辑了部分文件路径):
/Users/…/PycharmProjects/GoogleAPIs/HelloYouTubeDataAPIOAuth.py
Loading Credentials From File...
Refreshing Access Token...
Traceback (most recent call last):
File "/Users/.../PycharmProjects/GoogleAPIs/HelloYouTubeDataAPIOAuth.py", line 23, in <module>
credentials.refresh(Request())
File "/Users/.../PycharmProjects/GoogleAPIs/venv/lib/python3.9/site-packages/google/oauth2/credentials.py", line 200, in refresh
access_token, refresh_token, expiry, grant_response = _client.refresh_grant(
File "/Users/.../PycharmProjects/GoogleAPIs/venv/lib/python3.9/site-packages/google/oauth2/_client.py", line 248, in refresh_grant
response_data = _token_endpoint_request(request, token_uri, body)
File "/Users/.../PycharmProjects/GoogleAPIs/venv/lib/python3.9/site-packages/google/oauth2/_client.py", line 124, in _token_endpoint_request
_handle_error_response(response_body)
File "/Users/.../PycharmProjects/GoogleAPIs/venv/lib/python3.9/site-packages/google/oauth2/_client.py", line 60, in _handle_error_response
raise exceptions.RefreshError(error_details, response_body)
google.auth.exceptions.RefreshError: ('invalid_grant: Bad Request', '{\n "error": "invalid_grant",\n "error_description": "Bad Request"\n}')
Process finished with exit code 1
我可以通过从我的目录中删除“youtube\u data\u token\u brand.pickle”文件并重新运行该程序(然后该程序要求我使用我的google帐户登录,并通过OAuth2步骤手动重新授权访问)来绕过这些错误
这让我相信我的刷新令牌即将过期(我发誓我在文档中的某个地方读到,在撤销访问权之前,它不应该过期——我还没有这样做——但在反复搜索之后,我再也找不到它了)
有趣的是,我能够为我控制的另一个YouTube帐户运行相同的程序,而该帐户没有遇到相同的刷新令牌错误问题。我还能够使用相同的token.pickle方法将刷新令牌存储到其他Google API(Google Analytics、YouTube Analytics等)中,但没有遇到任何问题
提前感谢您提供的任何帮助
刷新令牌可能会过期的原因有很多。主要的一点是,每次代码运行时,如果身份验证服务器返回一个新的刷新令牌,而您没有存储它,那么在运行五十次之后,您存储的刷新令牌将过期
注意:身份验证服务器不会每次都返回新的刷新令牌,而是会刷新访问令牌。这似乎是基于C#的一些语言,php没有,我认为node也没有。我还没有找到发生这种情况的原因,我怀疑这是在库中发生的,我不确定python库是否做到了这一点,但无论哪种方式,都最好让它处理事情
看看这段代码,它允许库处理刷新令牌的所有存储。您似乎正在手动执行很多操作。这可能会也可能不会导致您的刷新令牌后悔
你可能还想确保用户没有通过他们的google帐户撤销你的访问权限,不过我想你已经检查过了
在阅读了@stvar在其中一个答案中发布的official documentation之后,问题似乎是这个特定的刷新令牌总是有一周的寿命。这只是因为我的处境是一场“完美风暴”:
唯一的解决方案似乎是发布OAuth同意屏幕应用程序
根据official documentation,刷新令牌失效的一种情况是与相应刷新令牌关联的应用程序撤销其操作权限
刷新令牌失效的另一种情况是,当相应的帐户已超过授予的最大刷新令牌数时:
你可以检查一下,这确实是发生在account's permission page上的事情
相关问题 更多 >
编程相关推荐