我寫了一個小小的Python腳本,該腳本應該使用Python的requests
模塊訪問描述爲here的IBM Bluemix容器API。IBM Bluemix身份驗證令牌始終無效
下面是腳本:
"""
You can run this script for example as follows:
python test-script.py \
--user <YOUR IBM BLUEMIX USER NAME> \
--ca-certificate <PATH TO YOUR ca.pem> \
--oauth-token "$(cf oauth-token)" \
--space-id "$(cf space dev --guid)" \
--request-url https://containers-api.ng.bluemix.net/v3/containers/version \
--method GET
The request-url is an EXAMPLE!
"""
import argparse
import getpass
import requests
import json
# for parsing arguments provided on command line
parser = argparse.ArgumentParser()
parser.add_argument(
'-u', '--user',
required=True,
help='Specify the username for IBM Bluemix.',
)
parser.add_argument(
'-c', '--ca-certificate',
required=True,
help='Specify the location of the certificate of the trusted certification authority (ca.pem).'
)
parser.add_argument(
'-t', '--oauth-token',
required=True,
help='Specify your IBM Bluemix oauth-token.'
)
parser.add_argument(
'-s', '--space-id',
required=True,
help='Specify your IBM Bluemix space id (cf space <your space> --guid). Beware, the space needs to be available in the region you are logged in to (US South, United Kindom).'
)
parser.add_argument(
'-l', '--request-url',
required=True,
default='https://containers-api.ng.bluemix.net/v3/containers/version',
help='Specify the URL you want to send the request to.'
)
parser.add_argument(
'-m', '--method',
default='GET',
help='Specify the HTTP method.'
)
args = parser.parse_args()
def run_script():
password = getpass.getpass(prompt='IBM Bluemix password:')
# for now hard coded
headers = {
'Accept': 'application/json',
'X-Auth-Token': args.oauth_token,
'X-Auth-Project-Id': args.space_id
}
# first we get the appropriate HTTP request method
request_method = getattr(requests, args.method.lower())
# then we try to make the request with that method
try:
response = request_method(
args.request_url,
auth=(args.user, password),
data=None, # expects a dict or json.dumps return type
verify=args.ca_certificate,
headers=headers
)
print(response)
print(response.json())
except Exception as exc:
print('ERROR!')
def main():
try:
run_script()
except KeyboardInterrupt as exc:
exit('Interrupted, exiting ...')
main()
這個腳本我打電話:
python script.py \
--user <IBM Bluemix login name> \
--ca-certificate /home/<USER>/.ice/certs/containers-api.eu-gb.bluemix.net/<ID>/ca.pem \
--oauth-token "$(cf oauth-token)" \
--space-id "$(cf space dev --guid)" \
--request-url https://containers-api.ng.bluemix.net/v3/images/json \
--method GET
對於--user
參數我試過幾件事情:
- 名字加上姓氏從IBM Bluemix儀表板頁面以兩個空格之間的空格作爲字符串
"
- 完整的電子郵件我用於註冊,這也標記
User:
當我做cf login
- 組織名稱,其中顯示,當我做
cf login
至於--space-id
和身份驗證令牌--oauth-token
: APi本身的文檔讓我按照自己的方式獲得它們。我也嘗試通過複製&粘貼我使用的子命令的粘貼,並從腳本中將它們打印出來,以確保它們全部進入腳本。它的確如此。
--request-url
參數值我也從API文檔中獲得了,通過使用「Try it」按鈕並複製顯示的curl
命令的URL,這被用於嘗試,因此也應該是正確的。
但是,在每個需要身份驗證的請求中(例如列出空間中所有圖像的請求),我從API獲得401
響應,告訴我身份驗證令牌無效,我應該嘗試執行再次使用cf login
和cf ic init
。做到這一點,不會更改我的令牌或任何東西,並且不會修復錯誤。
下面是一個例子迴應,我得到:
<Response [401]>
{'code': 'IC5097E',
'description': "Authentication was not successful: bearer <SOME ID> Please login via 'cf login ...' + 'cf ic init ...' and try again.",
'environment': 'prod-dal09',
'host_id': '176',
'incident_id': '<SOME ID>',
'name': 'InvalidToken',
'rc': '401',
'type': 'Infrastructure'}
(我打破了線,以使其更具可讀性這裏SO)
所以我不知道我做錯了與令牌。我如何使用身份驗證令牌創建正確的請求?
編輯#1
我也使用解碼的https://jwt.io/ JSON網絡令牌。它顯示我輸入的用戶名確實是該令牌包含的用戶名。
編輯#2
我還檢查(再次)的空間可用:
正如你可以看到有一個在這兩個地區命名爲dev
空間。
這解決了它。我登錄了1個區域,但使用了另一個區域的API,認爲它是獨立的。然後'cf oauth-token'爲請求URL返回了錯誤的標記。另外需要知道的是,不能使用'cf oauth-token'的完整輸出,而只能使用'承載'(即承載空間)之後的所有輸出。 – Zelphir