2024年5月25日 星期六

Python 如何使用 Json 通過 JWT 請求獲取 Box Accese Token (不使用boxsdk)

Python 如何使用 Json 通過 JWT 請求獲取 Box Accese Token (不使用boxsdk)

方法是參考自這篇的步驟說明

SDKを使用しないJWT - Box Developerドキュメント

以及這個的官方示例後修改而來
samples-docs-authenticate-with-jwt-api/sample.3.py


如果需要在 PwerShell 上的版本可以參考這個 PsJwt 專案中的範例
PsJwt/Example/Get-BoxToken at main · hunandy14/PsJwt (github.com)


下面讓我們開始正文吧如何一步一步的獲取到令牌



讀取 config.json 文件

這份文件可以通過這個教學一步步取得
SDKを使用しないJWT - Box Developerドキュメント

總之就是需要你在個人的 Box 帳號中註冊一個應用程式,並且在註冊後必須由經由該網域的Admin帳號同意權限請求才能使用。如果該帳號就是 Admin 則可以自己審核自己。

import json
from cryptography.hazmat.backends import default_backend
from cryptography.hazmat.primitives.serialization import load_pem_private_key

# 讀取 config.json 文件
with open('config.json') as json_file:
    config = json.load(json_file)

# 從配置中加載 PEM 私鑰
key = load_pem_private_key(
    data=config["boxAppSettings"]["appAuth"]["privateKey"].encode('utf8'),
    password=config["boxAppSettings"]["appAuth"]["passphrase"].encode('utf8'),
    backend=default_backend(),
)

這個很簡單就是把東西讀取出來而已,並把加密的私鑰先解密出來。



建立 JWT claims 聲明

建立 JWT claims 聲明

import secrets
import time

# 設定認證 URL
authentication_url = 'https://api.box.com/oauth2/token'

# 建立 JWT claims 用於認證
claims = {
    'iss': config['boxAppSettings']['clientID'],  # 客戶端 ID
    'sub': config['enterpriseID'],                # 企業 ID
    'box_sub_type': 'enterprise',                 # 認證類型
    'aud': authentication_url,                    # 受眾 URL
    'jti': secrets.token_hex(64),                 # JWT ID,用於唯一性
    'exp': round(time.time()) + 45                # 過期時間 (45 秒後)
}

這個聲明最終會變成發送給 Box 伺服器的資訊



建立 JWT assertions

有了 claims 之後,我們需要用這些聲明來生成一個 JWT token。這個 token 將會用來向 Box 的認證服務請求 Access Token。

import jwt

# 建立 JWT assertion
assertion = jwt.encode(
    claims, 
    key, 
    algorithm='RS512',
    headers={
        'kid': config['boxAppSettings']['appAuth']['publicKeyID']
    }
)

這段程式碼使用 pyjwt 庫來對 claims 進行簽名。key 是我們之前解密出的私鑰,而 algorithm 指定了我們使用 RS512 來進行簽名。

JWT token 驗證可以參考這個網站 JSON Web Tokens - jwt.io ,他可以動態驗證你的 JWT 是否正確,如果輸入私鑰也可以動態生成



發送請求以獲取 Access Token

我們現在需要將生成的 JWT token 發送到 Box 的認證伺服器,以換取一個 Access Token。

import requests

# 發送請求以獲取存取權杖
response = requests.post(
    authentication_url, {
        'grant_type': 'urn:ietf:params:oauth:grant-type:jwt-bearer',
        'assertion': assertion,
        'client_id': config['boxAppSettings']['clientID'],
        'client_secret': config['boxAppSettings']['clientSecret']
    }
)
# 解析回應並獲取存取權杖
access_token = response.json()['access_token']
print(f"AccessToken: {access_token}")

這裡使用 requests 庫發送 HTTP POST 請求到 Box 的認證伺服器。回應中包含了我們需要的 Access Token。

這個就是最終的成品了,可以拿來直接對 Box API 伺服器請求操作你的帳號了。



驗證 Access Token 

接下來,我們將使用獲取的 Access Token 來驗證身份,並且可以進一步操作 Box API。這邊就做一個簡單的測試查詢當前帳號是誰。

這部分就直接引用 boxsdk 測試比較快,目的只是測試獲取的令牌是否可用,也可以通過 response 的方式手動獲取請求。

from boxsdk import OAuth2, Client

# 使用 OAuth2 認證
auth = OAuth2(
    client_id=config['boxAppSettings']['clientID'],
    client_secret=config['boxAppSettings']['clientSecret'],
    access_token=access_token,
)

# 創建 Box 客戶端
client = Client(auth)
# 獲取用戶資訊
user = client.user().get()
print('Authenticated as:', user.name)

這段程式碼使用 boxsdk 庫來創建一個 Box 客戶端,並使用 Access Token 進行身份驗證。最後我們打印出已驗證用戶的名稱。



驗證 Access Token 2

這是直接透過 requests 跟 Box 伺服器交互的方法,會稍微麻煩一點,還得自己解構回傳的信息字串。

在這個方法中,我們不使用 boxsdk 庫,而是直接使用 requests 庫來發送 HTTP 請求,並手動處理回應。這樣可以更靈活地控制 API 請求和回應。

import requests

# 發送請求到 Box API 以獲取當前用戶資訊
response = requests.get(
    'https://api.box.com/2.0/users/me',
    headers={
        'Authorization': f'Bearer {access_token}',
    }
)

# 檢查請求是否成功
if response.status_code == 200:
    user_info = response.json()
    print('Authenticated as:', user_info['name'])
else:
    print('Failed to authenticate')
    print('Response:', response.text)

這段程式碼做了以下幾件事:

  1. 設置請求頭:使用獲取的 Access Token 設置請求頭中的 Authorization 字段。
  2. 發送 GET 請求:向 Box API 發送 GET 請求,以獲取當前用戶的資訊。請求的 URL 是 https://api.box.com/2.0/users/me
  3. 處理回應:檢查回應的狀態碼。如果狀態碼是 200,表示請求成功,然後解析回應的 JSON 數據並打印出用戶名稱。如果請求失敗,打印回應的錯誤信息。

通過這種方式,你可以手動處理 Box API 的所有回應,這在需要進行更複雜的錯誤處理或自定義 API 請求時特別有用。




沒有留言:

張貼留言