ETrade api - 无效的消费者密钥和/或会话令牌

问题描述

当我尝试在沙箱 (https://apisb.eTrade.com/v1/accounts/list) 中向 ETrade 的 Account List 端点发出请求时,我收到 HTTP 401 -“未经授权的请求 - 无效的消费者密钥和/或会话令牌”。

我不明白为什么这个请求不起作用,因为我成功调用Get Access Token API,检索了 oauth_tokenoauth_token_secret 并使用它们来签署和发出请求到帐户列表。

更让我困惑的是,我下载了官方的 Etrade Python Client,在调用帐户列表之前放置了一个断点,并确认我的代码在给定相同的请求参数的情况下生成了完全相同的 oauth_signature .

此外,我实际上复制了官方 Python 客户端生成的所有请求参数并将它们粘贴到我的网络浏览器中,但仍然收到相同的“未经授权的请求 - 无效的消费者密钥和/或会话令牌”响应。>

为了说明,这里是我在官方 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_@R_404_4868@)

(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 客户端向 url 添加.json,但无论是否包含 .json,我仍然收到未经授权的错误

我还尝试将 OAuth 参数作为 HTTP 标头而不是 URL 参数发送,但我仍然遇到相同的错误

我还在我的请求中对 URL 参数进行了 rfc3986 编码(百分比编码),这适用于获取访问令牌请求,但不适用于帐户列表请求。

请注意,我将以下 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

我还能尝试调试什么?

解决方法

想通了:

问题在于,由于我从网络浏览器(Chrome 扩展程序)发送请求,我的请求包含 Cookie,这导致 API 产生会话错误。

我正在使用 Fetch API。 在 {"credentials": "omit"} 参数中设置 init 会忽略 Cookie 标头并解决问题。