[AWS 開發筆記] Node.js 串接 S3 免金鑰!深入解析 SDK 自動驗證機制
在開發 Node.js 應用程式並串接 AWS 服務(如上傳檔案到 S3)時,很多開發者第一直覺是建立一個 IAM User,然後將 accessKeyId 和 secretAccessKey 寫入程式碼或 .env 檔中。但這樣做不僅管理麻煩,還存在金鑰外洩的風險。
其實,如果你的程式是跑在 AWS 環境(如 EC2、Lambda 或 EKS)上,你根本不需要手動管理這些金鑰。本文將教你如何利用 IAM Role 與 AWS SDK 的自動搜尋機制,實現更安全、更簡潔的權限驗證。
1. 原理:AWS SDK 是如何「自動」找到權限的?
當你在 Node.js 中初始化 S3Client 卻沒有手動輸入 accessKeyId 和 secretAccessKey 時,AWS SDK 並不會報錯,而是會啟動一個自動搜尋機制(Default Credentials Provider Chain)。
這個機制會檢查「現在是誰在執行這段程式」,並根據執行環境自動抓取對應的憑證:
- EC2 環境:
SDK 會嘗試存取 EC2 的 Instance Metadata Service (IMDS)。這是一個內部的 API(通常位於
http://169.254.169.254...),AWS 內部會自動換發「臨時憑證」並放在這個路徑下,SDK 會自動去讀取並使用它。 - Lambda 環境: AWS 會自動將臨時憑證(包含 AccessKey, SecretKey, SessionToken)注入到執行環境的環境變數 (Environment Variables) 中,SDK 會優先讀取這些變數。
- EKS (Kubernetes) 環境: 透過 OIDC 機制,將 Token 掛載到 Pod 內的檔案中,並透過環境變數告知 SDK 檔案位置。
2. 實作教學:程式碼該怎麼寫?
實作的關鍵字就是:「保持空白」。
你不需要在程式碼中寫死任何金鑰,只需要告訴 SDK 你所在的 Region 即可。SDK 會自動依照順序查找:先看環境變數,再看 IAM Role 的臨時憑證;如果你是在本地電腦開發,它甚至會自動去讀取你 ~/.aws/credentials 設定檔裡的 Profile。
✅ 推薦寫法
import { S3Client } from "@aws-sdk/client-s3";
// 只要不傳入 credentials 參數,SDK 就 會自動去抓 IAM Role
const s3 = new S3Client({
region: "ap-northeast-1",
});
// 接下來就可以直接使用 s3 進行 PutObject 等操作...
總結來說:
- 在 AWS Console: 將權限設定好的 IAM Role 綁定給你的 EC2、Lambda 或 ECS Task。
- 在 Node.js 程式: 初始化
new S3Client時什麼都不用填(除了 Region)。 - 背後原理: SDK 會自動去敲 AWS 內部的「後門 API」(Instance Metadata) 來拿鑰匙。
3. 驗證:如何確認目前使用的是哪個 Role?
如果你想確認程式碼是否真的成功抓到了 IAM Role,或者想 Debug 目前的身分,可以使用 AWS 的 STS (Security Token Service) 來檢查。
你可以使用 GetCallerIdentityCommand 來查看目前的 ARN:
import { STSClient, GetCallerIdentityCommand } from "@aws-sdk/client-sts";
const sts = new STSClient({ region: "ap-northeast-1" });
async function checkIdentity() {
try {
const response = await sts.send(new GetCallerIdentityCommand({}));
console.log("目前的身份 ARN:", response.Arn);
// 成功時會顯示類似:arn:aws:sts::123456789012:assumed-role/你的角色名/i-xxxxxx
} catch (err) {
console.error("無法取得身分:", err);
}
}
checkIdentity();
如果成功,你會看到 assumed-role 的字樣,代表程式已經成功扮演了你設定的角色。
為什麼要這樣做?
除了程式碼更乾淨之外,最大的好處是安全性。
透過 IAM Role 取得的憑證是「臨時的」,AWS 會每隔一段時間自動更新這把鑰匙。相比於你自己將 Access Key 寫死在程式碼中(永久金鑰),這種方式能大幅降低金鑰外洩後的風險。
簡單的比喻:
把 Access Key 寫死在程式碼裡,就像是把家裡大門的備份鑰匙藏在門口地毯下,誰翻到誰就能進去,而且這把鑰匙永遠有效。
使用 IAM Role,則像是佩戴了公司的電子識別證。當你走進公司(AWS 環境),感應門(SDK)會自動識別你的身分並讓你通行。這張識別證是系統自動發配的,而且具有時效性,就算被複製,過一段時間也就失效了。