After authorizing my application, I request an access token by passing the oauth credentials through the header. The signature and headers are generated through this code;
API_module = 'oauth'
API_RESTful = 'access_token'
if renewal:
API_RESTful = 'renew_access_token'
production_url = 'https://etws.etrade.com/{0:s}/{1:s}'.format(API_module, API_RESTful)
oauth_timestamp = int(time.time())
rand_str = lambda n: ''.join([random.choice(string.hexdigits) for i in range(n)])
oauth_nonce = rand_str(40)
key = oauth_consumer_secret + \
'&' + \
quote_plus(oauth_token_secret)
base_string = quote_plus('GET') + '&' + \
quote_plus('https://etws.etrade.com/oauth/access_token') + '&' + \
quote_plus('oauth_consumer_key={}&'.format(oauth_consumer_key)) + \
quote_plus('oauth_nonce={}&'.format(oauth_nonce)) + \
quote_plus('oauth_signature_method=HMAC-SHA1&') + \
quote_plus('oauth_timestamp={:d}&'.format(oauth_timestamp)) + \
quote_plus('oauth_token={}&'.format(quote_plus(oauth_token))) + \
quote_plus('oauth_verifier={}'.format(oauth_verification_code))
hashed = hmac.new(key.encode(), base_string.encode(), sha1)
oauth_signature = quote_plus(binascii.b2a_base64(hashed.digest())[:-1])
header_string = 'Authorization: OAuth ' + \
'realm="",' + \
'oauth_signature="{}",'.format(oauth_signature) + \
'oauth_nonce="{}",'.format(quote_plus(oauth_nonce)) + \
'oauth_signature_method="{}",'.format(oauth_signature_method) + \
'oauth_consumer_key="{}",'.format(oauth_consumer_key) + \
'oauth_timestamp="{}",'.format(str(oauth_timestamp)) + \
'oauth_verifier="{}",'.format(oauth_verification_code) + \
'oauth_token="{}"'.format(quote_plus(oauth_token))
headers_list.append(header_string)
response = curl_get_http(current_url=production_url)
produces these headers;
Host: etws.etrade.com
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Connection: keep-alive
Authorization: OAuth
realm="",
oauth_signature="fzqLbI8LBlBGs1Clp4eAgs09YuM%3D",
oauth_nonce="E447Ea1FCfbcCF0116fbdC47bE8E4aA4Cf7e3Aab",
oauth_signature_method="HMAC-SHA1",
oauth_consumer_key="4b6471c7ee",
oauth_timestamp="1501003943",
oauth_verifier="O5K2A",
oauth_token="BVuKV9Q7F93OxjbqY%2FzRmoqI0M%3D"
the request returns;
oauth_token=3W3hs5aSQPwMR%2FM0H0%2BPWhI%2Bo%3D&oauth_token_secret=SWvknmgEIgKzbN35bwwoNw%3D
The key is updated by replacing the old token_secret with the new token_secret. The base string is also updated with the new token value and with a new time stamp and nonce. These new values are used to generate a new signature.
url_quotes = 'https://etws.etrade.com/market/rest/quote/{0:s}?detailFlag={1:s}'.format(symbols, flag)
oauth_timestamp = int(time.time())
rand_str = lambda n: ''.join([random.choice(string.hexdigits) for i in range(n)])
oauth_nonce = rand_str(40)
key = oauth_consumer_secret + \
'&' + \
oauth_token_secret
base_string = quote_plus('GET') + '&' + \
quote_plus('https://etws.etrade.com/market/rest/quote') + '&' + \
quote_plus('oauth_consumer_key={}&'.format(oauth_consumer_key)) + \
quote_plus('oauth_nonce={}&'.format(oauth_nonce)) + \
quote_plus('oauth_signature_method=HMAC-SHA1&') + \
quote_plus('oauth_timestamp={:d}&'.format(oauth_timestamp)) + \
quote_plus('oauth_token={}&'.format(oauth_token)) #+ \
#quote_plus('oauth_verifier={}'.format(oauth_verification_code))
hashed = hmac.new(key.encode(), base_string.encode(), sha1)
oauth_signature = quote_plus(binascii.b2a_base64(hashed.digest())[:-1])
header_string = 'Authorization: OAuth ' + \
'realm="",' + \
'oauth_signature="{}",'.format(oauth_signature) + \
'oauth_nonce="{}",'.format(quote_plus(oauth_nonce)) + \
'oauth_signature_method="{}",'.format(oauth_signature_method) + \
'oauth_consumer_key="{}",'.format(oauth_consumer_key) + \
'oauth_timestamp="{:d}",'.format(oauth_timestamp) + \
'oauth_verifier="{}",'.format(oauth_verification_code) + \
'oauth_token="{}"'.format(oauth_token)
headers_list.append(header_string)
response = curl_get_http(current_url=url_quotes)
Changing the headers to;
Host: etws.etrade.com
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Connection: keep-alive
Authorization: OAuth
realm="",
oauth_signature="v4xa%2FrCKtFRSUdHw%3D",
oauth_nonce="57FCC260F81b2fAd95AccA69FE07BFFcd06d83AB",
oauth_signature_method="HMAC-SHA1",
oauth_consumer_key="4b6471c7ee",
oauth_timestamp="1501003945",
oauth_verifier="O5K2A",
oauth_token="3W3hs5aSQPwMR%2FM0H0%2BPWhI%2Bo%3D"
and a get_quote request is made;
https://etws.etrade.com/market/rest/quote/TICK,ER,THAT,GOES,UP?detailFlag=FUNDAMENTAL
Though, instead of a quote, an oauth problem is returned.
<Error>
<message>oauth_problem=signature_invalid</message>
</Error>
I have tried passing the information in the url, but it returns the same error. Are there procedural errors in the request? Should the new token be used without updating the signature?
(the posted credentials have been changed to protect the innocent)