当我尝试在沙盒 ( ) 中向 Etrade 的帐户列表端点发出请求https://apisb.etrade.com/v1/accounts/list
时,我收到 HTTP 401 -“未经授权的请求 - 无效的消费者密钥和/或会话令牌”。
我不明白为什么这个请求不起作用,因为我成功地调用了Get Access Token API,检索oauth_token
并oauth_token_secret
使用它们来签名并向 Account List 发出请求。
为了增加我的困惑,我下载了官方的Etrade Python 客户端,在调用帐户列表之前放置了一个断点,并确认我的代码在oauth_signature
给定相同的请求参数的情况下生成完全相同的代码。
此外,我实际上复制了官方 Python 客户端生成的所有请求参数并将它们粘贴到我的 Web 浏览器中,并且仍然得到相同的“未经授权的请求 - 无效的消费者密钥和/或会话令牌”响应。
为了说明,这是我在官方 Python 客户端中放置的断点(我已将敏感键的前四个字母替换为“123a”):
Breakpoint 1 at /Users/me/Downloads/EtradePythonClient/venv/lib/python3.9/site-packages/rauth/session.py:210
(Pdb) c
> /Users/me/Downloads/EtradePythonClient/venv/lib/python3.9/site-packages/rauth/session.py(210)request()
-> return super(OAuth1Session, self).request(method, url, **req_kwargs)
(Pdb) pprint.pprint(oauth_params)
{'oauth_consumer_key': '123a01814e407344bc2b385f3954679b',
'oauth_nonce': '8230791e8c0253518a6b2dec8120b643fde93745',
'oauth_signature': '123apxtEaUJmlvKFWv7zz+lfNk4=',
'oauth_signature_method': 'HMAC-SHA1',
'oauth_timestamp': 1614559929,
'oauth_token': '123aMSpwaaWItBDgXQ/Te4M9363WSULWFdeHkh18B8s=',
'oauth_version': '1.0'}
(Pdb) url
'https://apisb.etrade.com/v1/accounts/list.json'
(Pdb) method
'GET'
使用上述内容,我构建了以下 URL 并将其粘贴到我的网络浏览器中:
https://apisb.etrade.com/v1/accounts/list.json?oauth_consumer_key=123a01814e407344bc2b385f3954679b&oauth_nonce=8230791e8c0253518a6b2dec8120b643fde93745&oauth_signature_method=HMAC-SHA1&oauth_timestamp=1614559929&oauth_token=123aMSpwaaWItBDgXQ/Te4M9363WSULWFdeHkh18B8s=&oauth_version=1.0&oauth_signature=123apxtEaUJmlvKFWv7zz+lfNk4=
但我收到 HTTP 401 响应 - “未经授权的请求 - 无效的使用者密钥和/或会话令牌”。
然而,该请求在官方 Python 客户端中有效(只要我不先在浏览器中尝试,否则我会在 Python 客户端中收到“错误:oauth_problem=nonce_used”错误)。
我注意到的一件事是官方 Python 客户端添加了oauth_version=1.0
参数,但是无论我是否包含该参数并使用它签名,我的请求仍然失败。我还注意到官方 Python 客户端.json
在 url 中添加了一个,但无论我是否包含.json
.
我还尝试将 OAuth 参数作为 HTTP 标头而不是 URL 参数发送,但我仍然收到相同的错误。
我也是 rfc3986-encoding (percent-encoding) 我的请求中的 URL 参数,它适用于 Get Access Token 请求,但不适用于 Account List 请求。
请注意,我将以下 URL 用于请求令牌、访问令牌和沙盒 API:
https://apisb.etrade.com/oauth/request_token
https://us.etrade.com/e/t/etws/authorize?key=${oauth_consumer_key}&token=${state.oauth_token}
https://apisb.etrade.com/oauth/access_token
https://apisb.etrade.com/v1/accounts/list
我还能尝试调试什么?