在無伺服器架構中,API Gateway 是前端與後端的主要橋樑,但若缺乏嚴格的身份驗證與授權,API 容易被濫用或惡意存取,透過與 Cognito 整合,能以權杖(JWT Token)為核心,確保只有合法使用者能調用 API,兼顧安全與便利。
此 Lab 著重在 API 存取控制,讓前端呼叫後端服務時不再依靠靜態金鑰或弱密碼,而是以 Cognito 產生的權杖進行驗證,這能有效避免未授權存取,並成為後續 API 保護與 RBAC(角色型存取控制)的基礎。
白話來說,通常便於用戶,很多網站都會開發API的功能(像是快速做網頁內的任何操作),通常是用找到指定的API網址 + 使用被授權的角色/金鑰,就能快速取用該功能,而並非每次操作都要透過UI圖像介面。
而本次的實驗就是為了這個金鑰可以更安全,所以跟Cognito一起搭配,讓你的API不會被濫用。
(1) JWT Token 驗證:API Gateway 會自動驗證傳入的 JWT Token,包括其簽名、發行者(Issuer)和有效期限。
(2) Access Token vs. ID Token:建議使用 Access Token 作為 API 認證的依據,而非 ID Token。ID Token 主要是用來驗證使用者身分,而 Access Token 則是用來授權存取後端服務。
(3) Token 過期時間:設定合理的 Token 過期時間(一般建議 1 小時),避免長時間有效的 Token 遭竊取濫用。
(4 )擴展性:除了基本的驗證,你還可以結合 WAF(Web Application Firewall)進一步防禦惡意流量,或使用 Lambda Authorizer 實現更細緻的 RBAC(角色存取控制)。
(5)由於Day11中已啟用MFA,而MFA的驗證碼有時效限制,建議直接寫一個自動化腳本執行獲取AccessToken,並執行API。
♦可用JWT專用的Decoder工具來解碼:https://www.jwt.io/
進入「Lambda」服務頁面。
點選「創建函數」。
輸入函數名稱、選用指定的代碼編輯器、執行角色,並按下建立。
退出推薦的模板。
撰寫Lambda內容+部署。
程式碼範例
export const handler = async (event) => {
const response = {
statusCode: 200,
body: JSON.stringify('Hello, your token is valid! Then you can use the API to create some functions now. :3'),
};
return response;
};
創建一個新的APP Client。
選用非「傳統 Web 應用程式」及「Machine-to-machine應用程式」的應用程式用戶端及輸入APP名稱,並創建。
💡有「用戶端秘密(Client secret)」的APP Client無法使用session交換到Cognito的AccessToken或是IdToken,這是後面會執行的動作。
創建完成畫面。
編輯現在的應用程式用戶端(APP Client)。
新增「ALLOW_USER_PASSWORD_AUTH」權限。
完成修改。
進入「API Gateway」服務頁面。
點選「建立API」。
選用「HTTP API」。
創建API名稱及整合後端要使用的Lambda函數。
選用HTTP獲取方式及路徑。
定義名稱(使用預設即可)。
確認創建。
確認路由路徑有整合Lambda。(表示經過API gateway後,會執行什麼動作)
創建一個新的授權方。
創建授權方。
https://cognito-idp.<Region>.amazonaws.com/<userpoolID>
Cognito「userpoolID」在哪裡?
對象(用戶端ID)在哪?
授權成功畫面。(表示要通過授權方驗證才能通過API Gateway)
透過終端機(terminal)向Cognito取得 session
。
第一段
aws cognito-idp initiate-auth \
--auth-flow USER_PASSWORD_AUTH \
--client-id <Cognito_APP_CLIENT_ID> \
--auth-parameters USERNAME=<username>,PASSWORD=<password>
透過終端機(terminal),用 session
向Cognito拿到對應的 IdToken
或 AccessToken
。
第二段
aws cognito-idp respond-to-auth-challenge \
--client-id <Cognito_APP_CLIENT_ID> \
--challenge-name SOFTWARE_TOKEN_MFA \
--session <上一步回傳的Session> \
--challenge-responses USERNAME=<username>,SOFTWARE_TOKEN_MFA_CODE=<六位數驗證碼>
透過終端機(terminal),用 curl
測試是否API可以成功獲得授權,取得API Gateway後端運行的服務結果。
第三段(建議使用AccessToken)
curl -H "Authorization: Bearer <IdToken或AccessToken>" \
https://<api_id>.execute-api.<region>.amazonaws.com/hello
401 Unauthorized
本 Lab 將 Cognito 與 API Gateway 整合,實現以 JWT Token 為基礎的 API 安全機制,確保只有通過 Cognito 認證的使用者才能調用 API。這大幅提升 API 的安全性,避免未授權存取,並為後續的角色授權與存取管控打下基礎。
[1] AWS API gateway - 使用 API Gateway 中的 JWT 授權方來控制對 HTTP API 的存取:
https://docs.aws.amazon.com/zh_tw/apigateway/latest/developerguide/http-api-jwt-authorizer.html
[2] AWS Cognito - 使用應用程式用戶端的應用程式特定設定:
https://docs.aws.amazon.com/cognito/latest/developerguide/user-pool-settings-client-apps.html#user-pool-settings-client-app-client-types
【補充】
JWKS URI 包含有關簽署使用者權杖之私有金鑰的公開資訊。您可以在以下位置找到使用者集區的 JWKS URI(參照:https://docs.aws.amazon.com/zh_tw/cognito/latest/developerguide/amazon-cognito-user-pools-using-tokens-verifying-a-jwt.html),範例如下(未來可能會失效):
https://cognito-idp.us-east-1.amazonaws.com/us-east-1_0Kius6YBt/.well-known/jwks.json