使用mastodon.py遇invalid_grant错误,如何改用OAuth2授权流程?
使用取自mastodon.py README的代码:
import os from mastodon import Mastodon USERNAME_AS_EMAIL = os.environ["USERNAME_AS_EMAIL"] PASSWORD = os.environ["PASSWORD"] APP_NAME = "APP_NAME" Mastodon.create_app( APP_NAME, api_base_url = 'https://mastodon.social', to_file = 'pytooter_clientcred.secret' ) mastodon = Mastodon( client_id = 'pytooter_clientcred.secret', api_base_url = 'https://mastodon.social' ) mastodon.log_in( USERNAME_AS_EMAIL, PASSWORD, to_file = 'pytooter_usercred.secret' ) mastodon = Mastodon( client_id = 'pytooter_clientcred.secret', access_token = 'pytooter_usercred.secret', api_base_url = 'https://mastodon.social' )
在mastodon.social实例运行后出现错误:
Traceback (most recent call last): File
"C:\Users\matth\GitHub\feed_thing\again.py", line 32, in
mastodon.log_in( File "C:\Users\matth.virtualenvs\feed_thing-LXMa84iN\lib\site-packages\mastodon\Mastodon.py",
line 568, in log_in
raise MastodonIllegalArgumentError('Invalid user name, password, or redirect_uris: %s' % e)
mastodon.Mastodon.MastodonIllegalArgumentError: Invalid user name,
password, or redirect_uris: ('Mastodon API returned error', 400, 'Bad
Request', 'invalid_grant')
更新:该错误仅出现在mastodon.social实例,mstdn.social、ohai.social等实例无此问题。经排查原因是账号开启了双因素认证,原代码未采用OAuth2授权流程,需替换代码实现OAuth2授权。
开启双因素认证后,必须使用OAuth2授权码流程登录,以下是修改后的代码:
import os from mastodon import Mastodon APP_NAME = "APP_NAME" API_BASE_URL = 'https://mastodon.social' # 1. 创建应用(仅需运行一次,后续可注释) Mastodon.create_app( APP_NAME, api_base_url=API_BASE_URL, to_file='pytooter_clientcred.secret', # 指定外带回调URI,适配无本地服务器的场景 redirect_uris='urn:ietf:wg:oauth:2.0:oob' ) # 2. 初始化客户端 mastodon = Mastodon( client_id='pytooter_clientcred.secret', api_base_url=API_BASE_URL ) # 3. 获取授权链接,引导用户在浏览器完成授权并获取授权码 auth_url = mastodon.auth_request_url( scopes=['read', 'write', 'follow'], # 根据需求设置权限范围 redirect_uri='urn:ietf:wg:oauth:2.0:oob' ) print("请访问以下链接完成授权:", auth_url) auth_code = input("输入页面显示的授权码:") # 4. 使用授权码获取访问令牌并保存 mastodon.log_in( code=auth_code, redirect_uri='urn:ietf:wg:oauth:2.0:oob', to_file='pytooter_usercred.secret' ) # 5. 用保存的令牌初始化客户端(后续运行可直接使用这段) mastodon = Mastodon( client_id='pytooter_clientcred.secret', access_token='pytooter_usercred.secret', api_base_url=API_BASE_URL ) # 测试:发布一条状态验证登录成功 mastodon.status_post("通过OAuth2授权码流程登录成功!")
关键说明
- 授权流程:
urn:ietf:wg:oauth:2.0:oob是无本地服务器场景下的标准回调方式,用户授权后会得到一串授权码,手动输入到程序即可完成验证。 - 权限范围:
scopes参数可根据实际需求调整,常用权限包括read(读取账号数据)、write(发布内容)、follow(管理关注关系)。 - 重复运行:首次运行需完成应用创建和授权流程,后续可注释掉创建应用、获取授权链接的代码,直接用保存的令牌文件初始化客户端。
内容的提问来源于stack exchange,提问作者MatthewMartin

