使用Python3的E * Trade API的get_quote中的标头和oauth [英] headers and oauth in get_quote for E*Trade API using Python3

查看:109
本文介绍了使用Python3的E * Trade API的get_quote中的标头和oauth的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在授权我的应用程序之后,我通过在标头中传递oauth凭据来请求访问令牌.签名和标头是通过此代码生成的;

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)

产生这些标题;

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"

请求返回;

oauth_token=3W3hs5aSQPwMR%2FM0H0%2BPWhI%2Bo%3D&oauth_token_secret=SWvknmgEIgKzbN35bwwoNw%3D

通过用新的token_secret替换旧的token_secret来更新密钥.基本字符串也将使用新的令牌值以及新的时间戳和随机数进行更新.这些新值用于生成新签名.

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)

将标题更改为;

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"

并进行get_quote请求;

and a get_quote request is made;

https://etws.etrade.com/market/rest/quote/TICK,ER,THAT,GOES,UP?detailFlag=FUNDAMENTAL

尽管,不是报价,而是返回了oauth问题.

Though, instead of a quote, an oauth problem is returned.

<Error>
<message>oauth_problem=signature_invalid</message>
</Error>

我尝试在url中传递信息,但是它返回相同的错误.请求中是否存在程序错误?是否应在不更新签名的情况下使用新令牌?

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)

推荐答案

问题出在签名生成上.

对于URL部分,应包括完整的URL,直到查询字符串为止.在此示例中,它将是:

For the URL portion, you should include the full URL up to the query string. In this example it would be:

base_string = quote_plus('GET') + '&' + \
          quote_plus('https://etws.etrade.com/market/rest/quote/TICK,ER,THAT,GOES,UP') + '&' + \

在串联oauth参数时,还应该包括所有非Oauth查询参数.它们需要按照规范进行排序( https://oauth.net/core/1.0 a/#anchor13 ).在这种情况下,您需要将detailFlag = FUNDAMENTAL作为第一个参数:

When concatenating the oauth parameters you should include all non-Oauth query parameters as well. They need to be in sorted order per the spec (https://oauth.net/core/1.0a/#anchor13). In this case you would need to include detailFlag=FUNDAMENTAL as your first parameter:

quote_plus('detailFlag=FUNDAMENTAL&') + \ 
quote_plus('oauth_consumer_key={}&'.format(oauth_consumer_key)) + \

此外,标头中不需要oauth_verifier即可检索访问令牌.

Also, the oauth_verifier is not needed in the header except to retrieve the access token.

这篇关于使用Python3的E * Trade API的get_quote中的标头和oauth的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆