0

When I attempt to make a request to Etrade's Account List endpoint in sandbox (https://apisb.etrade.com/v1/accounts/list), I am getting an HTTP 401 - "Unauthorized request - invalid Consumer key and/or session token".

I don't understand why this request is not working, since I am successfully calling the Get Access Token API, retrieving the oauth_token and oauth_token_secret and using them to sign and make the request to Account List.

To add to my confusion, I downloaded the official Etrade Python Client, put a breakpoint right before the account list is called, and confirmed that my code is generating the exact same oauth_signature given the same request parameters.

Furthermore, I actually copied all of the request parameters generated by the official Python client and pasted them into my web browser, and am still getting the same "Unauthorized request - invalid Consumer key and/or session token" response.

To illustrate, here is a breakpoint I put in the official Python client (I've replaced the first four letters of sensitive keys with "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'

Using the above, I constructed the following URL and pasted it into my web browser:

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=

but I get an HTTP 401 response - "Unauthorized request - invalid Consumer key and/or session token".

And yet, the request works in the official Python client (as long as I don't try it in my browser first, otherwise I will get a 'Error: oauth_problem=nonce_used' error in the Python client).

One thing I noticed is that the official Python client adds the oauth_version=1.0 parameter, but my requests are still failing whether or not I include that parameter and sign with it. I also noticed the official Python client adds a .json to the url, but again I am still getting the unauthorized error whether or not I include .json.

I've also tried sending the OAuth parameters as an HTTP Header instead of as URL parameters, but I still get the same error.

I'm also rfc3986-encoding (percent-encoding) the URL parameters in my request, which is working for the Get Access Token request but not the Account List request.

Note that I am using the following URLs for request token, access token, and API for sandbox:

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

What else I can try to debug this?

mark
  • 4,678
  • 7
  • 36
  • 46

1 Answers1

0

Figured it out:

The problem was that, since I'm sending my requests from a web browser (a Chrome extension), my request was including a Cookie, which was causing the API to produce a session error.

I am using the Fetch API. Setting {"credentials": "omit"} in the init parameter omits the Cookie header and solves the issue.

mark
  • 4,678
  • 7
  • 36
  • 46