我已经设置了对网站的API访问权限,并且可以使用其测试GUI界面使用用户名,密码和API密钥进行连接(HTTP 200)。
如果我尝试下面的代码,则会收到错误响应403:
from requests.auth import HTTPDigestAuth
url = 'https://website.com'
result = requests.get(url, auth=HTTPDigestAuth('username', 'password'))
我认为我需要在原始requests.get
中包含API密钥,但是我不确定该怎么做。
这是一个REST API。在网站上,我通过提供名称来生成API密钥,然后设置API登录详细信息(用户名和密码)。在HTTP请求的信息下,它列出了请求标头组件:
X-API-KEY:k API密钥k(从“我的帐户”获得)是我们识别和授权调用应用程序的方式
CST /授权(有效),用于标识客户端。
X-SECURITY-TOKEN / ACCOUNT-ID (有效帐户令牌或帐户ID),用于标识客户的当前帐户。
内容类型:application / json 。请求格式类型。应始终按照仅对json的指示进行设置
接受:application / json; charset = UTF-8 响应格式类型。应始终按照仅针对json的指示进行设置版本:
版本:v API版本v(如果未指定,则默认为1)
标题是否可能包含API密钥,用户名和密码?用户名和密码不用于设置API密钥。
答案 0 :(得分:2)
您似乎正在使用IG Labs REST Trading API;文档指出,有两种身份验证方式,具体取决于您指定的API版本。您引用的标头文档是所涉及的不同标头的总体概述。该部分对于实际了解该API的身份验证/授权的工作方式不是很有用。
在同一页面上是身份验证和授权部分,您需要研究的是该部分。这是描述两种认证方式的地方。还有一个separate examples section解释了两种不同的模式如何与显示的具体请求和响应一起工作。
要进行身份验证,您必须首先向/session
route发送一个POST
请求,并在X-IG-API-KEY
标头中显示您的API密钥。这是您需要用户名和密码的地方。然后,有效的用户名/密码会为您提供安全令牌,用于后续请求。对于API版本1和2,可以包含一个附加字段encryptedPassword
,以说明密码是纯文本还是加密的;否则,请参见图4。您只需要满足IG Singapore login restrictions,就可以安全地省略该字段。
对于v1和v2请求,您在响应头中获得了这些令牌,API版本v3在正文中提供了所需的信息。令牌的寿命有限。 v1 / v2令牌的有效期为6个小时,但是通过使用这些令牌进行请求后,它们会自动延长至72个小时,然后您需要再次登录。 v3令牌仅在60秒内有效。,但是单独的refresh_token
可以通过将刷新令牌发送到/session/refresh-token
endpoint来获得新令牌。
V1 / v2请求然后在/session
响应中使用完全相同的标头中使用令牌,因此在CST
(“客户端会话令牌”)和X-SECURITY-TOKEN
标头之间进行复制而你在路上。
V3请求使用标准的OAuth Authorization
标头,方法设置为Bearer
。只需使用access_token
结构中的oauthToken
值构造该标头,并保存refresh_token
到access_token
到期时为止。该文档还建议您设置IG-ACCOUNT-ID
标头以标识帐户(令牌仅标识客户)。
我强烈建议您使用requests.Session()
object简化标头处理。
对于API的v1和v2,请使用:
import requests
url = 'https://website.com'
API_KEY = '.... your API key ....'
username = 'username'
password = 'password'
session = requests.Session()
# these are sent along for all requests
session.headers['X-IG-API-KEY'] = API_KEY
# not strictly needed, but the documentation recommends it.
session.headers['Accept'] = "application/json; charset=UTF-8"
# log in first, to get the tokens
response = session.post(
url + '/session',
json={'identifier': username, 'password': password},
headers={'VERSION': '2'},
)
response.raise_for_status() # if not a 2xx response, raise an exception
# copy across the v1/v2 tokens
session.headers['CST'] = response.headers['CST']
session.headers['X-SECURITY-TOKEN'] = response.headers['X-SECURITY-TOKEN']
现在,您已设置为使用session
继续访问API。
对于v3,令牌位于JSON主体中:
session = requests.Session()
# these are sent along for all requests
session.headers['X-IG-API-KEY'] = API_KEY
# log in first, to get the tokens
response = session.post(
url + '/session',
json={'identifier': username, 'password': password},
headers={'VERSION': '3'},
)
response.raise_for_status() # if not a 2xx response, raise an exception
response_data = response.json()
oauth_tokens = response_data['oauthToken']
session.headers['Authorization'] = 'Bearer ' + oauth_tokens['access_token']
session.headers['IG-ACCOUNT-ID'] = response_data['accountId']
现在,您已设置为使用session
来继续访问API,直到经过oauth._tokens['expires_in']
秒或给出401响应:
if response.status == 401 and response.json()['errorCode'] == 'error.security.oauth-token-invalid':
# refresh required, old token is done.
然后您需要使用session.post(url + '/session/refresh-token', json={'refresh_token': oauth_tokens['refresh_token']}) to get a fresh
oauthToken`结构:
# refresh the access token
del session.headers['Authorization']
response = session.post(
url + '/session/refresh-token',
json={'refresh_token': oauth_tokens['refresh_token']},
headers={'VERSION': '1'},
)
response.raise_for_status() # if not a 2xx response, raise an exception
oauth_tokens = response.json()
session.headers['Authorization'] = 'Bearer ' + oauth_tokens['access_token']
请注意,我会继续向每个单独的请求发送VERSION
标头;他们的API使用版本号每个端点,因此/session
有3个版本,但是/session/refresh-token
仅具有版本1,您不能将VERSION
设置为任何版本否则它会破坏。
V3 /session
格式似乎比较麻烦,但是该版本可以让您无限期地刷新访问权限,前提是您在最后一次使用令牌后的10分钟内进行了刷新;无论您做什么,V1 / V2访问令牌都将在充值72小时后过期。