英文:
Etrade API Oauth 1.0 flow fails with invalid oauth_signature
问题
我想使用Go和Postman对Etrade API进行身份验证。我正在按照官方的Etrade API开发者文档进行操作:
我成功地完成了他们提供的Python示例中的Oauth 1.0流程(稍作修改以打印一些会话属性):
$ python3 etrade_python_client.py
1) Sandbox Consumer Key
2) Live Consumer Key
3) Exit
Please select Consumer Key Type: 2
Please accept agreement and enter verification code from browser: REDACTED
access_token_response: <Response [200]>
access_token: REDACTED
access_token_secret: REDACTED
但是,我尝试使用Go或Postman实现Oauth 1.0进行身份验证时一直无法成功。对于Go,我使用dghubble/oauth1库编写了这个示例客户端,对于Postman,我使用内置的身份验证工具。
我的问题主要是在每个实现中生成正确的oauth_signature
。我总是收到以下错误:
或者,如果我尝试将我从Etrade的Python示例客户端获取的访问令牌直接插入到Postman中,例如在访问/accounts/list
API端点时,我收到的响应是:
<Error>
<message>oauth_problem=signature_invalid</message>
</Error>
奇怪的是,他们的Python示例(使用rauth)与Go或Postman有不同的行为。似乎Etrade做了一些不符合requests.Session
实现的非标准操作。有没有办法知道我是否正确生成了任何实现所需的签名?
附录:
Postman示例请求:
使用Python rauth
库时的会话属性捕获(敏感信息已打码):
https://gist.github.com/natemurthy/a7f628e44da9651d0676291803915c9c
Python与Go调用/v1/accounts/list
时的HTTP头部比较:
Python:
GET https://api.etrade.com/v1/accounts/list.json
{'Authorization': 'OAuth realm="",oauth_consumer_key=REDACTED",oauth_nonce="22d0b83e4cba610148c990fdab1c327948a10677",oauth_signature_method="HMAC-SHA1",oauth_timestamp="1668988571",oauth_token="REDACTED",oauth_version="1.0",oauth_signature="REDACTED"'}
Response: 200 OK
Go:
GET https://api.etrade.com/v1/accounts/list.json
map[Authorization:[OAuth oauth_consumer_key="REDACTED", oauth_nonce="eZ1twhwIs7f3wD90uOelpuNNAE2RZ8wkQm4gEKvlklM%3D", oauth_signature="REDACTED", oauth_signature_method="HMAC-SHA1", oauth_timestamp="1669074040", oauth_token="REDACTED", oauth_version="1.0"]]
Response: 401 Unauthorized
{"Error":{"message":"oauth_problem=signature_invalid"}}
英文:
I would like to authenticate against the Etrade API using Go and Postman. I am following the official Etrade API Developer Docs:
I successfully completed the Oauth 1.0 flow using the Python example they provided (with some slight modifications to print some of the session attributes):
$ python3 etrade_python_client.py
1) Sandbox Consumer Key
2) Live Consumer Key
3) Exit
Please select Consumer Key Type: 2
Please accept agreement and enter verification code from browser: REDACTED
access_token_response: <Response [200]>
access_token: REDACTED
access_token_secret: REDACTED
But I have had no success authenticating using the Go or Postman implementations of Oauth 1.0. For Go, I wrote this sample client using the dghubble/oauth1 library, and for Postman I am using the built-in auth tool.
My trouble is largely with generating the correct oauth_signature
in each of these. I always get this error:
Or if I try to plug-and-play the access token I obtained from Etrade's sample Python client into Postman when, for instance, accessing the /accounts/list
API endpoint, the response I receive is:
<Error>
<message>oauth_problem=signature_invalid</message>
</Error>
It's strange that their Python example (which uses rauth) has a different behavior than Go or Postman. Seems that Etrade does something non-standard that fits the requests.Session
shape of the rauth
implementation. Is there a way to know if I'm generating my signatures correctly for any implementation I use?
Appendix:
Sample Postman requests:
Capture of session attributes when using Python rauth
library (sensitive info redacted):
https://gist.github.com/natemurthy/a7f628e44da9651d0676291803915c9c
Comparison of HTTP headers when calling /v1/accounts/list
between Python vs Go:
Python:
GET https://api.etrade.com/v1/accounts/list.json
{'Authorization': 'OAuth realm="",oauth_consumer_key=REDACTED",oauth_nonce="22d0b83e4cba610148c990fdab1c327948a10677",oauth_signature_method="HMAC-SHA1",oauth_timestamp="1668988571",oauth_token="REDACTED",oauth_version="1.0",oauth_signature="REDACTED"'}
Response: 200 OK
Go:
GET https://api.etrade.com/v1/accounts/list.json
map[Authorization:[OAuth oauth_consumer_key="REDACTED", oauth_nonce="eZ1twhwIs7f3wD90uOelpuNNAE2RZ8wkQm4gEKvlklM%3D", oauth_signature="REDACTED", oauth_signature_method="HMAC-SHA1", oauth_timestamp="1669074040", oauth_token="REDACTED", oauth_version="1.0"]]
Response: 401 Unauthorized
{"Error":{"message":"oauth_problem=signature_invalid"}}
专注分享java语言的经验与见解,让所有开发者获益!
评论