全部產品
Search
文件中心

Alibaba Cloud SDK:管理訪問憑證

更新時間:Jun 06, 2026

在使用阿里雲SDK時,憑據資訊(例如AccessKey、STS Token等)由Credentials工具統一管理。本文將為您介紹Credentials工具支援的憑據類型及其配置方法,協助您快速掌握Credentials工具的使用。

背景資訊

憑據是指使用者證明其身份的一組資訊。使用者在系統中進行登入時,需要提供正確的憑據才能驗證身份。常見的憑據類型有:

  1. 阿里雲主帳號和RAM使用者的永久憑據 AccessKey(簡稱AK)是由AccessKey ID和AccessKey Secret組成的金鑰組。

  2. 阿里雲RAM角色的STS臨時訪問Token,簡稱STS Token。它是可以自訂時效和存取權限的臨時身份憑據,詳情請參見什麼是STS

  3. Bearer Token。它是一種身分識別驗證和授權的令牌類型。

前提條件

安裝Credentials工具

使用npm下載安裝。

npm install @alicloud/credentials

使用最新發行Credentials依賴包,確保所有憑證支援。版本列表請參見Releases · aliyun/credentials-nodejs · GitHub

Credentials工具配置參數介紹

Credentials工具的配置參數定義在@alicloud/credentials模組的Config 建構函式中,憑據類型由必填參數type指定。確定憑據類型後,需根據該憑據類型選擇相應的參數。下表將詳細介紹type的取值範圍及各類憑據類型所支援的參數。其中,表示必填參數,-表示選擇性參數,×表示不支援參數。

說明

未在下表中列出的憑據類型及參數表示不建議繼續使用。

type

access_key

sts

ram_role_arn

ecs_ram_role

oidc_role_arn

credentials_uri

bearer

accessKeyId:訪問憑據ID。

×

×

×

×

accessKeySecret:訪問憑據密鑰。

×

×

×

×

securityToken:STS Token。

×

-

×

×

×

×

roleArn:RAM角色的ARN。

×

×

×

×

×

roleSessionName:自訂會話名稱,預設格式為credentials-nodejs-目前時間的時間戳記

×

×

-

×

-

×

×

roleName:RAM角色名稱。

×

×

×

-

×

×

×

disableIMDSv1:是否強制使用加固模式,預設值為false

×

×

×

-

×

×

×

bearerToken:bearer token。

×

×

×

×

×

×

policy:自訂權限原則。

×

×

-

×

-

×

×

roleSessionExpiration:會話到期時間,預設3600秒。

×

×

-

×

-

×

×

oidcProviderArn:OIDC供應商ARN。

×

×

×

×

×

×

oidcTokenFilePath:OIDC Token檔案路徑。

×

×

×

×

×

×

externalId:角色外部 ID,主要功能是防止混淆代理人問題。更多資訊,請參見使用ExternalId防止混淆代理人問題

×

×

-

×

×

×

×

credentialsURI:憑證的URI。

×

×

×

×

×

×

STSEndpoint:STS的服務存取點,支援VPC服務存取點和公網服務存取點,可選的值請參見服務存取點,預設值為sts.aliyuncs.com

×

×

-

×

-

×

×

timeout:HTTP請求的讀逾時時間,預設值為5000毫秒。

×

×

-

-

-

-

×

connectTimeout:HTTP請求的連線逾時時間,預設值為10000毫秒。

×

×

-

-

-

-

×

初始化憑據用戶端

前文已介紹Credentials工具所支援的憑據類型及其配置參數,接下來將通過詳細的程式碼範例進一步說明,您可以根據具體情況選擇適合的使用方式。

重要
  • 在專案中使用明文AccessKey,容易因代碼倉庫許可權管理不當造成AccessKey泄露,會威脅該帳號下所有資源的安全。建議通過環境變數、設定檔等方式儲存AccessKey。

  • 在使用Credentials工具時,建議採用單例模式。這一做法能夠啟用Credentials工具內建的憑據緩衝功能,有效防止因多次調用介面而導致的限流問題,以及因建立多個執行個體而引起的資源浪費問題。詳細資料請參見Session類型憑據自動重新整理機制

方式一:使用預設憑據鏈

當您在初始化憑據用戶端不傳入任何參數時,Credentials工具會使用預設憑據鏈方式初始化用戶端。預設憑據的讀取邏輯請參見預設憑據鏈

const Credential = require('@alicloud/credentials');
// 不指定參數
const credentialClient = new Credential.default();
const credential = credentialClient.getCredential();
credential.then(credential => {
    console.log(credential);
});
import Credential from '@alicloud/credentials';
const credential = new Credential();
credential.getCredential().then(credential => {
    console.log(credential);
});

介面調用方法

本樣本以調用Elastic Compute Service的DescribeRegions介面為例,因此需先安裝ECS SDK

const Ecs20140526 = require('@alicloud/ecs20140526');
const OpenApi = require('@alicloud/openapi-client');
const Util = require('@alicloud/tea-util');
const Credential = require('@alicloud/credentials');
async function main() {
    // 使用預設憑證初始化Credentials Client。
    const credentialClient = new Credential.default();
    const ecsConfig = new OpenApi.Config({
        endpoint: 'ecs.cn-hangzhou.aliyuncs.com', // 配置雲產品服務接入地址(endpoint)。
        credential: credentialClient, // 使用Credentials配置憑證。
    });
    const ecsClient = new Ecs20140526.default(ecsConfig);
    const describeRegionsRequest = new Ecs20140526.DescribeRegionsRequest();
    const runtime = new Util.RuntimeOptions();
    ecsClient.describeRegionsWithOptions(describeRegionsRequest, runtime).then((result) => {
        console.log(JSON.stringify(result.body));
    });
}
main().catch(console.error);
import Ecs20140526, * as $Ecs20140526 from '@alicloud/ecs20140526';
import OpenApi, * as $OpenApi from '@alicloud/openapi-client';
import Util, * as $Util from '@alicloud/tea-util';
import Credential from '@alicloud/credentials';
export default class Client {
    static async main(): Promise<$Ecs20140526.DescribeRegionsResponse> {
        // 使用預設憑據初始化Credentials Client
        let credential = new Credential();
        let config = new $OpenApi.Config({
            credential: credential, // 使用Credentials配置憑證。
            endpoint: 'ecs.cn-hangzhou.aliyuncs.com', // 配置雲產品服務接入地址(endpoint)。
        });
        let client = new Ecs20140526(config);
        let describeRegionsRequest = new $Ecs20140526.DescribeRegionsRequest({});
        let runtime = new $Util.RuntimeOptions({});
        return await client.describeRegionsWithOptions(describeRegionsRequest, runtime);
    }
}
const response = Client.main();
response.then(res => {
    console.log(res.body?.regions);
});

方式二:使用AK

Credentials工具將使用您提供的AccessKey作為訪問憑據。

警告

阿里雲帳號(主帳號)擁有資源的全部許可權,AK一旦泄露,會給系統帶來巨大風險,不建議使用。

推薦使用最小化授權的RAM使用者的AK。

const Credential = require('@alicloud/credentials');
const credentialsConfig = new Credential.Config({
    // 憑證類型。
    type: 'access_key',
    // 設定accessKeyId值,此處已從環境變數中擷取accessKeyId為例。
    accessKeyId: process.env.ALIBABA_CLOUD_ACCESS_KEY_ID,
    // 設定accessKeySecret值,此處已從環境變數中擷取accessKeySecret為例。
    accessKeySecret: process.env.ALIBABA_CLOUD_ACCESS_KEY_SECRET,
});
const credentialClient = new Credential.default(credentialsConfig);
import Credential, { Config } from '@alicloud/credentials';
const credentialsConfig  = new Config({
    // 憑證類型。
    type: 'access_key',
    // 設定accessKeyId值,此處已從環境變數中擷取accessKeyId為例。
    accessKeyId: process.env.ALIBABA_CLOUD_ACCESS_KEY_ID,
    // 設定accessKeySecret值,此處已從環境變數中擷取accessKeySecret為例。
    accessKeySecret: process.env.ALIBABA_CLOUD_ACCESS_KEY_SECRET,
});
const credentialClient = new Credential(credentialsConfig);

介面調用方法

本樣本以調用Elastic Compute Service的DescribeRegions介面為例,因此需先安裝ECS SDK

const Ecs20140526 = require('@alicloud/ecs20140526');
const OpenApi = require('@alicloud/openapi-client');
const Util = require('@alicloud/tea-util');
const Credential = require('@alicloud/credentials');
async function main() {
    const credentialsConfig = new Credential.Config({
        // 憑證類型。
        type: 'access_key',
        // 設定accessKeyId值,此處已從環境變數中擷取accessKeyId為例。
        accessKeyId: process.env.ALIBABA_CLOUD_ACCESS_KEY_ID,
        // 設定accessKeySecret值,此處已從環境變數中擷取accessKeySecret為例。
        accessKeySecret: process.env.ALIBABA_CLOUD_ACCESS_KEY_SECRET,
    });
    const credentialClient = new Credential.default(credentialsConfig);
    const ecsConfig = new OpenApi.Config();
    ecsConfig.endpoint = 'ecs.cn-hangzhou.aliyuncs.com'; // 配置雲產品服務接入地址(endpoint)。
    ecsConfig.credential = credentialClient; // 使用Credentials配置憑證。
    const ecsClient = new Ecs20140526.default(ecsConfig);
    const describeRegionsRequest = new Ecs20140526.DescribeRegionsRequest();
    const runtime = new Util.RuntimeOptions();
    ecsClient.describeRegionsWithOptions(describeRegionsRequest, runtime).then((response) => {
        console.log(response.body.regions);
    });
}
main().catch(console.error);
import Ecs20140526, * as $Ecs20140526 from '@alicloud/ecs20140526';
import Credential, { Config } from '@alicloud/credentials';
import OpenApi, * as $OpenApi from '@alicloud/openapi-client';
import Util, * as $Util from '@alicloud/tea-util';
export default class Client {
    static async main(): Promise<$Ecs20140526.DescribeRegionsResponse> {
        const credentialsConfig = new Config({
            // 憑證類型。
            type: 'access_key',
            // 設定accessKeyId值,此處已從環境變數中擷取accessKeyId為例。
            accessKeyId: process.env.ALIBABA_CLOUD_ACCESS_KEY_ID,
            // 設定accessKeySecret值,此處已從環境變數中擷取accessKeySecret為例。
            accessKeySecret: process.env.ALIBABA_CLOUD_ACCESS_KEY_SECRET,
        });
        const credentialClient = new Credential(credentialsConfig);
        let config = new $OpenApi.Config({
            credential: credentialClient, // 使用Credentials配置憑證。
            endpoint: 'ecs.cn-hangzhou.aliyuncs.com', // 配置雲產品服務接入地址(endpoint)。
        });
        let client = new Ecs20140526(config);
        let describeRegionsRequest = new $Ecs20140526.DescribeRegionsRequest({});
        let runtime = new $Util.RuntimeOptions({});
        return await client.describeRegionsWithOptions(describeRegionsRequest, runtime);
    }
}
const response = Client.main();
response.then(res => {
    console.log(res.body?.regions);
});

方式三:使用STS Token

Credentials工具將使用您提供的靜態STS Token作為訪問憑據。

const Credential = require('@alicloud/credentials');
const credentialsConfig = new Credential.Config({
    type: 'sts',
    // 設定accessKeyId值,此處已從環境變數中擷取accessKeyId為例。
    accessKeyId: process.env.ALIBABA_CLOUD_ACCESS_KEY_ID,
    // 設定accessKeySecret值,此處已從環境變數中擷取accessKeySecret為例。
    accessKeySecret: process.env.ALIBABA_CLOUD_ACCESS_KEY_SECRET,
    // 設定securityToken值,此處已從環境變數中擷取securityToken為例。
    securityToken: process.env.ALIBABA_CLOUD_SECURITY_TOKEN,
});
const cred = new Credential.default(credentialsConfig);
import Credential, { Config } from '@alicloud/credentials';
const credentialsConfig = new Config({
    // 憑證類型。
    type: 'access_key',
    // 設定accessKeyId值,此處已從環境變數中擷取accessKeyId為例。
    accessKeyId: process.env.ALIBABA_CLOUD_ACCESS_KEY_ID,
    // 設定accessKeySecret值,此處已從環境變數中擷取accessKeySecret為例。
    accessKeySecret: process.env.ALIBABA_CLOUD_ACCESS_KEY_SECRET,
    // 設定securityToken值,此處已從環境變數中擷取securityToken為例。
    securityToken: process.env.ALIBABA_CLOUD_SECURITY_TOKEN,
});
const credentialClient = new Credential(credentialsConfig);

介面調用方法

本樣本以調用Elastic Compute Service的DescribeRegions介面為例,因此需先安裝Elastic Compute Service SDKSecurity Token Service SDK

const Ecs20140526 = require('@alicloud/ecs20140526');
const Sts20150401 = require('@alicloud/sts20150401');
const OpenApi = require('@alicloud/openapi-client');
const Util = require('@alicloud/tea-util');
const Credential = require('@alicloud/credentials');
async function assumeRole() {
    // 建立STS client,擷取STS token
    const stsConfig = new OpenApi.Config({
        endpoint: 'sts.cn-hangzhou.aliyuncs.com', // STS服務接入地址(endpoint)。
        accessKeyId: process.env.ALIBABA_CLOUD_ACCESS_KEY_ID, // 從環境變數中擷取 accessKeyId
        accessKeySecret: process.env.ALIBABA_CLOUD_ACCESS_KEY_SECRET, // 從環境變數中擷取 accessKeySecret
    });
    const stsClient = new Sts20150401.default(stsConfig);
    const assumeRoleRequest = new Sts20150401.AssumeRoleRequest({
        durationSeconds: 3600, // STS token有效時間
        roleArn: '<RoleArn>', // 要扮演的RAM角色ARN,樣本值:acs:ram::123456789012****:role/adminrole,可以通過環境變數ALIBABA_CLOUD_ROLE_ARN設定roleArn 
        roleSessionName: '<RoleSessionName>', // 自訂角色會話名稱,可以通過環境變數ALIBABA_CLOUD_ROLE_SESSION_NAME設定RoleSessionName 
        policy: '', // 權限原則集合,非必填。樣本值:{"Statement": [{"Action": ["*"],"Effect": "Allow","Resource": ["*"]}],"Version":"1"}
    });
    try {
        const assumeRoleResponsePromise = await stsClient.assumeRole(assumeRoleRequest);
        const assumeRoleResponseBodyCredentials = assumeRoleResponsePromise.body.credentials;
        return {
            accessKeyId: assumeRoleResponseBodyCredentials.accessKeyId,
            accessKeySecret: assumeRoleResponseBodyCredentials.accessKeySecret,
            securityToken: assumeRoleResponseBodyCredentials.securityToken,
        };
    } catch (error) {
        console.error('AssumeRole 請求失敗:', error);
        throw error;
    }
}
async function main() {
    const stsToken = await assumeRole()
    const credentialsConfig = new Credential.Config({
        // 憑證類型。
        type: 'sts',
        accessKeyId: stsToken.accessKeyId,
        accessKeySecret: stsToken.accessKeySecret,
        securityToken: stsToken.securityToken,
    });
    const credentialClient = new Credential.default(credentialsConfig);
    const ecsConfig = new OpenApi.Config({
        endpoint: 'ecs.cn-hangzhou.aliyuncs.com', // 配置雲產品服務接入地址(endpoint)。
        credential: credentialClient, // 使用Credentials配置憑證。
    })
    const ecsClient = new Ecs20140526.default(ecsConfig);
    const describeRegionsRequest = new Ecs20140526.DescribeRegionsRequest();
    const runtime = new Util.RuntimeOptions();
    // 調用DescribeRegions介面並獲得響應。
    ecsClient.describeRegionsWithOptions(describeRegionsRequest, runtime).then((response) => {
        console.log(response.body.regions);
    });
}
main().catch(console.error);
import Ecs20140526, * as $Ecs20140526 from '@alicloud/ecs20140526';
import Sts20150401, * as $Sts20150401 from '@alicloud/sts20150401';
import OpenApi, { Config } from '@alicloud/openapi-client';
import Util, * as $Util from '@alicloud/tea-util';
import Credential, { Config as CredentialConfig } from '@alicloud/credentials';
async function assumeRole() {
    // 建立STS client,擷取STS token
    const stsConfig = new Config({
        endpoint: 'sts.cn-hangzhou.aliyuncs.com', // STS服務接入地址(endpoint)。
        accessKeyId: process.env.ALIBABA_CLOUD_ACCESS_KEY_ID, // 從環境變數中擷取 accessKeyId
        accessKeySecret: process.env.ALIBABA_CLOUD_ACCESS_KEY_SECRET, // 從環境變數中擷取 accessKeySecret
    });
    const stsClient = new Sts20150401(stsConfig);
    const assumeRoleRequest = new $Sts20150401.AssumeRoleRequest({
        durationSeconds: 3600, // STS token有效時間
        roleArn: '<RoleArn>', // 要扮演的RAM角色ARN,樣本值:acs:ram::123456789012****:role/adminrole,可以通過環境變數ALIBABA_CLOUD_ROLE_ARN設定roleArn  
        roleSessionName: '<RoleSessionName>', // 自訂角色會話名稱,可以通過環境變數ALIBABA_CLOUD_ROLE_SESSION_NAME設定RoleSessionName 
        policy: '', // 權限原則集合,非必填。樣本值:{"Statement": [{"Action": ["*"],"Effect": "Allow","Resource": ["*"]}],"Version":"1"}
    });
    try {
        const assumeRoleResponsePromise = await stsClient.assumeRole(assumeRoleRequest);
        const assumeRoleResponseBodyCredentials = assumeRoleResponsePromise.body?.credentials;
        return {
            accessKeyId: assumeRoleResponseBodyCredentials?.accessKeyId,
            accessKeySecret: assumeRoleResponseBodyCredentials?.accessKeySecret,
            securityToken: assumeRoleResponseBodyCredentials?.securityToken,
        };
    } catch (error) {
        console.error('AssumeRole 請求失敗:', error);
        throw error;
    }
}
async function main() {
    const stsToken = await assumeRole()
    const credentialsConfig = new CredentialConfig({
        // 憑證類型。
        type: 'sts',
        accessKeyId: stsToken.accessKeyId,
        accessKeySecret: stsToken.accessKeySecret,
        securityToken: stsToken.securityToken,
    });
    const credentialClient = new Credential(credentialsConfig);
    const ecsConfig = new Config({
        endpoint: 'ecs.cn-hangzhou.aliyuncs.com', // 配置雲產品服務接入地址(endpoint)。
        credential: credentialClient, // 使用Credentials配置憑證。
    })
    const ecsClient = new Ecs20140526(ecsConfig);
    const describeRegionsRequest = new $Ecs20140526.DescribeRegionsRequest();
    const runtime = new $Util.RuntimeOptions();
    // 調用DescribeRegions介面並獲得響應。
    ecsClient.describeRegionsWithOptions(describeRegionsRequest, runtime).then((response) => {
        console.log(response.body?.regions);
    });
}
main().catch(console.error);

方式四:使用AK及RamRoleArn

該方式底層實現是STS Token。通過指定RAM角色的ARN(Alibabacloud Resource Name),Credentials工具可以協助開發人員前往STS換取STS Token。您也可以通過為policy賦值來限制RAM角色到一個更小的許可權集合。

const Credential = require('@alicloud/credentials');
const credentialsConfig = new Credential.Config({
    type: 'ram_role_arn',
    accessKeyId: process.env.ALIBABA_CLOUD_ACCESS_KEY_ID,
    accessKeySecret: process.env.ALIBABA_CLOUD_ACCESS_KEY_SECRET,
    // 要扮演的RAM角色ARN,樣本值:acs:ram::123456789012****:role/adminrole,可以通過環境變數ALIBABA_CLOUD_ROLE_ARN設定roleArn
    roleArn: '<RoleArn>',
    // 自訂角色會話名稱,可以通過環境變數ALIBABA_CLOUD_ROLE_SESSION_NAME設定RoleSessionName
    roleSessionName: '<RoleSessionName>',
    // 設定更小的權限原則,非必填。樣本值:{"Statement": [{"Action": ["*"],"Effect": "Allow","Resource": ["*"]}],"Version":"1"}
    policy: '<Policy>',
    roleSessionExpiration: 3600,
});
const cred = new Credential.default(credentialsConfig);
import Credential, { Config } from '@alicloud/credentials';
const credentialsConfig = new Config({
    type: 'ram_role_arn',
    accessKeyId: process.env.ALIBABA_CLOUD_ACCESS_KEY_ID,
    accessKeySecret: process.env.ALIBABA_CLOUD_ACCESS_KEY_SECRET,
    // 要扮演的RAM角色ARN,樣本值:acs:ram::123456789012****:role/adminrole,可以通過環境變數ALIBABA_CLOUD_ROLE_ARN設定roleArn
    roleArn: '<RoleArn>',
    // 自訂角色會話名稱,可以通過環境變數ALIBABA_CLOUD_ROLE_SESSION_NAME設定RoleSessionName
    roleSessionName: '<RoleSessionName>',
    // 設定更小的權限原則,非必填。樣本值:{"Statement": [{"Action": ["*"],"Effect": "Allow","Resource": ["*"]}],"Version":"1"}
    policy: '<Policy>',
    roleSessionExpiration: 3600,
});
const credentialClient = new Credential(credentialsConfig);

介面調用方法

本樣本以調用Elastic Compute Service的DescribeRegions介面為例,因此需先安裝ECS SDK

const Ecs20140526 = require('@alicloud/ecs20140526');
const OpenApi = require('@alicloud/openapi-client');
const Util = require('@alicloud/tea-util');
const Credential = require('@alicloud/credentials');
async function main() {
    const credentialsConfig = new Credential.Config({
        // 憑證類型。
        type: 'ram_role_arn',
        // 設定為AccessKey ID值。
        accessKeyId: process.env.ALIBABA_CLOUD_ACCESS_KEY_ID,
        // 設定為AccessKey Secret值。
        accessKeySecret: process.env.ALIBABA_CLOUD_ACCESS_KEY_SECRET,
        // 要扮演的RAM角色ARN,樣本值:acs:ram::123456789012****:role/adminrole,可以通過環境變數ALIBABA_CLOUD_ROLE_ARN設定roleArn
        roleArn: '<RoleArn>',
        // 自訂角色會話名稱,可以通過環境變數ALIBABA_CLOUD_ROLE_SESSION_NAME設定RoleSessionName
        roleSessionName: '<RoleSessionName>',
        // 設定更小的權限原則,非必填。樣本值:{"Statement": [{"Action": ["*"],"Effect": "Allow","Resource": ["*"]}],"Version":"1"}
        policy: '<Policy>',
        roleSessionExpiration: 3600,
    });
    const credentialClient = new Credential.default(credentialsConfig);
    const ecsConfig = new OpenApi.Config({
        endpoint: 'ecs.cn-hangzhou.aliyuncs.com', // 配置雲產品服務接入地址(endpoint)。
        credential: credentialClient, // 使用Credentials配置憑證。
    });
    const ecsClient = new Ecs20140526.default(ecsConfig);
    const describeRegionsRequest = new Ecs20140526.DescribeRegionsRequest();
    const runtime = new Util.RuntimeOptions();
    // 調用DescribeRegions介面並獲得響應。
    const response = ecsClient.describeRegionsWithOptions(describeRegionsRequest, runtime);
    console.log((await response).body.regions);
}
main().catch(console.error);
import Ecs20140526, * as $Ecs20140526 from '@alicloud/ecs20140526';
import Credential, { Config } from '@alicloud/credentials';
import OpenApi, * as $OpenApi from '@alicloud/openapi-client';
import Util, * as $Util from '@alicloud/tea-util';
export default class Client {
    static async main(): Promise<$Ecs20140526.DescribeRegionsResponse> {
        const credentialsConfig = new Config({
            type: 'ram_role_arn',
            accessKeyId: process.env.ALIBABA_CLOUD_ACCESS_KEY_ID,
            accessKeySecret: process.env.ALIBABA_CLOUD_ACCESS_KEY_SECRET,
            // 要扮演的RAM角色ARN,樣本值:acs:ram::123456789012****:role/adminrole,可以通過環境變數ALIBABA_CLOUD_ROLE_ARN設定roleArn
            roleArn: '<RoleArn>',
            // 自訂角色會話名稱,可以通過環境變數ALIBABA_CLOUD_ROLE_SESSION_NAME設定RoleSessionName
            roleSessionName: '<RoleSessionName>',
            // 設定更小的權限原則,非必填。樣本值:{"Statement": [{"Action": ["*"],"Effect": "Allow","Resource": ["*"]}],"Version":"1"}
            policy: '<Policy>',
            roleSessionExpiration: 3600,
        });
        const credentialClient = new Credential(credentialsConfig);
        let config = new $OpenApi.Config({
            credential: credentialClient, // 使用Credentials配置憑證。
            endpoint: 'ecs.cn-hangzhou.aliyuncs.com', // 配置雲產品服務接入地址(endpoint)。
        });
        let client = new Ecs20140526(config);
        let describeRegionsRequest = new $Ecs20140526.DescribeRegionsRequest({});
        let runtime = new $Util.RuntimeOptions({});
        return await client.describeRegionsWithOptions(describeRegionsRequest, runtime);
    }
}
const response = Client.main();
response.then(res => {
    console.log(res.body?.regions);
});

方式五:使用ECS執行個體RAM角色

ECS和ECI執行個體均支援綁定執行個體RAM角色,運行於執行個體中的程式可通過Credentials工具自動擷取該角色的STS Token,從而完成憑據用戶端的初始化。

Credentials工具將預設採用加固模式(IMDSv2)訪問ECS的中繼資料服務(Meta Data Server),在使用加固模式時若發生異常,將使用普通模式兜底來擷取訪問憑據。您也可以通過設定參數disableIMDSv1或環境變數ALIBABA_CLOUD_IMDSV1_DISABLE,執行不同的異常處理邏輯:

  • 當值為false(預設)時,會使用普通模式繼續擷取訪問憑據。

  • 當值為true時,表示只能使用加固模式擷取訪問憑據,會拋出異常。

服務端是否支援IMDSv2,取決於您在伺服器的配置。

另外,您可以通過配置環境變數ALIBABA_CLOUD_ECS_METADATA_DISABLED=true來關閉ECS中繼資料的憑證訪問。

說明
const Credential = require('@alicloud/credentials');
const credentialsConfig = new Credential.Config({
    type: 'ecs_ram_role',
    // 選填,該ECS角色的角色名稱,不填會自動擷取,但是建議加上以減少請求次數,可以通過環境變數ALIBABA_CLOUD_ECS_METADATA設定roleName
    roleName: '<RoleName>',
    // 選填,預設值:false。true:表示強制使用加固模式。false:系統將首先嘗試在加固模式下擷取憑據。如果失敗,則會切換到普通模式(IMDSv1)進行嘗試
    // disableIMDSv1: true,
});
const cred = new Credential.default(credentialsConfig);
import Credential, { Config } from '@alicloud/credentials';
const credentialsConfig = new Config({
    type: 'ecs_ram_role',
    // 選填,該ECS角色的角色名稱,不填會自動擷取,但是建議加上以減少請求次數,可以通過環境變數ALIBABA_CLOUD_ECS_METADATA設定roleName
    roleName: '<RoleName>',
    // 選填,預設值:false。true:表示強制使用加固模式。false:系統將首先嘗試在加固模式下擷取憑據。如果失敗,則會切換到普通模式(IMDSv1)進行嘗試
    // disableIMDSv1: true,
});
const credentialClient = new Credential(credentialsConfig);

介面調用方法

本樣本以調用Elastic Compute Service的DescribeRegions介面為例,因此需先安裝ECS SDK

const Ecs20140526 = require('@alicloud/ecs20140526');
const OpenApi = require('@alicloud/openapi-client');
const Util = require('@alicloud/tea-util');
const Credential = require('@alicloud/credentials');
async function main() {
    const credentialsConfig = new Credential.Config({
        // 憑證類型。
        type: 'ecs_ram_role',
        // 選填,該ECS角色的角色名稱,不填會自動擷取,但是建議加上以減少請求次數,可以通過環境變數ALIBABA_CLOUD_ECS_METADATA設定roleName
        roleName: '<RoleName>',
    });
    const credentialClient = new Credential.default(credentialsConfig);
    const ecsConfig = new OpenApi.Config({
        endpoint: 'ecs.cn-hangzhou.aliyuncs.com', // 配置雲產品服務接入地址(endpoint)。
        credential: credentialClient, // 使用Credentials配置憑證。
    });
    const ecsClient = new Ecs20140526.default(ecsConfig);
    const describeRegionsRequest = new Ecs20140526.DescribeRegionsRequest();
    const runtime = new Util.RuntimeOptions();
    // 調用DescribeRegions介面並獲得響應。
    const response = ecsClient.describeRegionsWithOptions(describeRegionsRequest, runtime);
    console.log((await response).body.regions);
}
main().catch(console.error);
import Ecs20140526, * as $Ecs20140526 from '@alicloud/ecs20140526';
import Credential, { Config } from '@alicloud/credentials';
import OpenApi, * as $OpenApi from '@alicloud/openapi-client';
import Util, * as $Util from '@alicloud/tea-util';
export default class Client {
    static async main(): Promise<$Ecs20140526.DescribeRegionsResponse> {
        const credentialsConfig = new Config({
            type: 'ecs_ram_role',
            // 選填,該ECS角色的角色名稱,不填會自動擷取,但是建議加上以減少請求次數,可以通過環境變數ALIBABA_CLOUD_ECS_METADATA設定roleName
            roleName: '<RoleName>',
            // 選填,預設值:false。true:表示強制使用加固模式。false:系統將首先嘗試在加固模式下擷取憑據。如果失敗,則會切換到普通模式(IMDSv1)進行嘗試
            // disableIMDSv1: true,
        });
        const credentialClient = new Credential(credentialsConfig);
        let config = new $OpenApi.Config({
            credential: credentialClient, // 使用Credentials配置憑證。
            endpoint: 'ecs.cn-hangzhou.aliyuncs.com', // 配置雲產品服務接入地址(endpoint)。
        });
        let client = new Ecs20140526(config);
        let describeRegionsRequest = new $Ecs20140526.DescribeRegionsRequest({});
        let runtime = new $Util.RuntimeOptions({});
        return await client.describeRegionsWithOptions(describeRegionsRequest, runtime);
    }
}
const response = Client.main();
response.then(res => {
    console.log(res.body?.regions);
});

方式六:使用OIDCRoleArn

若您使用OIDC認證協議,並已建立OIDC身份供應商的RAM角色,您可以通過Credentials工具傳入OIDC身份供應商ARN、OIDC Token及RAM角色ARN,系統將自動調用AssumeRoleWithOIDC介面擷取RAM角色的STS Token,並將該STS Token作為訪問憑據。通過此方式擷取的憑據支援自動重新整理,詳情請參見Session類型憑據自動重新整理機制。例如當您的應用程式運行於已啟用RRSA功能的ACK叢集中時,Credentials工具支援通過讀取Pod環境變數中的OIDC配置資訊,調用AssumeRoleWithOIDC介面擷取服務角色的STS Token,從而利用該STS Token訪問阿里雲相關服務。

const Credential = require('@alicloud/credentials');
const credentialsConfig = new Credential.Config({
    type: 'oidc_role_arn',
    // RAM角色名稱ARN,可以通過環境變數ALIBABA_CLOUD_ROLE_ARN設定roleArn
    roleArn: '<RoleArn>',
    // OIDC供應商ARN,可以通過環境變數ALIBABA_CLOUD_OIDC_PROVIDER_ARN設定oidcProviderArn
    oidcProviderArn: '<OidcProviderArn>',
    // OIDC Token檔案路徑,可以通過環境變數ALIBABA_CLOUD_OIDC_TOKEN_FILE設定oidcTokenFilePath
    oidcTokenFilePath: '<OidcTokenFilePath>',
    // 自訂角色會話名稱,可以通過環境變數ALIBABA_CLOUD_ROLE_SESSION_NAME設定roleSessionName
    roleSessionName: '<RoleSessionName>',
    // 設定更小的權限原則,非必填。樣本值:{"Statement": [{"Action": ["*"],"Effect": "Allow","Resource": ["*"]}],"Version":"1"}
    policy: '<Policy>',
    // 設定session到期時間
    roleSessionExpiration: 3600,
});
const credentialClient = new Credential.default(credentialsConfig);
import Credential, { Config } from '@alicloud/credentials';
const credentialsConfig = new Config({
    type: 'oidc_role_arn',
    // RAM角色名稱ARN,可以通過環境變數ALIBABA_CLOUD_ROLE_ARN設定roleArn
    roleArn: '<RoleArn>',
    // OIDC供應商ARN,可以通過環境變數ALIBABA_CLOUD_OIDC_PROVIDER_ARN設定oidcProviderArn
    oidcProviderArn: '<OidcProviderArn>',
    // OIDC Token檔案路徑,可以通過環境變數ALIBABA_CLOUD_OIDC_TOKEN_FILE設定oidcTokenFilePath
    oidcTokenFilePath: '<OidcTokenFilePath>',
    // 自訂角色會話名稱,可以通過環境變數ALIBABA_CLOUD_ROLE_SESSION_NAME設定roleSessionName
    roleSessionName: '<RoleSessionName>',
    // 設定更小的權限原則,非必填。樣本值:{"Statement": [{"Action": ["*"],"Effect": "Allow","Resource": ["*"]}],"Version":"1"}
    policy: '<Policy>',
    // 設定session到期時間
    roleSessionExpiration: 3600,
});
const credentialClient = new Credential(credentialsConfig);

介面調用方法

本樣本以調用Elastic Compute Service的DescribeRegions介面為例,因此需先安裝ECS SDK

const Ecs20140526 = require('@alicloud/ecs20140526');
const OpenApi = require('@alicloud/openapi-client');
const Util = require('@alicloud/tea-util');
const Credential = require('@alicloud/credentials');
async function main() {
    const credentialsConfig = new Credential.Config({
        // 憑證類型。
        type: 'oidc_role_arn',
        // RAM角色名稱ARN,可以通過環境變數ALIBABA_CLOUD_ROLE_ARN設定roleArn
        roleArn: '<RoleArn>',
        // OIDC供應商ARN,可以通過環境變數ALIBABA_CLOUD_OIDC_PROVIDER_ARN設定oidcProviderArn
        oidcProviderArn: '<OidcProviderArn>',
        // OIDC Token檔案路徑,可以通過環境變數ALIBABA_CLOUD_OIDC_TOKEN_FILE設定oidcTokenFilePath
        oidcTokenFilePath: '<OidcTokenFilePath>',
        // 角色會話名稱,可以通過環境變數ALIBABA_CLOUD_ROLE_SESSION_NAME設定roleSessionName
        roleSessionName: '<RoleSessionName>',
        // 設定更小的權限原則,非必填。樣本值:{"Statement": [{"Action": ["*"],"Effect": "Allow","Resource": ["*"]}],"Version":"1"}
        policy: '<Policy>',
        // 設定session到期時間
        roleSessionExpiration: 3600,
    });
    const credentialClient = new Credential.default(credentialsConfig);
    const ecsConfig = new OpenApi.Config({
        endpoint: 'ecs.cn-hangzhou.aliyuncs.com', // 配置雲產品服務接入地址(endpoint)。
        credential: credentialClient, // 使用Credentials配置憑證。
    });
    const ecsClient = new Ecs20140526.default(ecsConfig);
    const describeRegionsRequest = new Ecs20140526.DescribeRegionsRequest();
    const runtime = new Util.RuntimeOptions();
    // 調用DescribeRegions介面並獲得響應。
    const response = ecsClient.describeRegionsWithOptions(describeRegionsRequest, runtime);
    console.log((await response).body.regions);
}
main().catch(console.error);
import Ecs20140526, * as $Ecs20140526 from '@alicloud/ecs20140526';
import Credential, { Config } from '@alicloud/credentials';
import OpenApi, * as $OpenApi from '@alicloud/openapi-client';
import Util, * as $Util from '@alicloud/tea-util';
export default class Client {
    static async main(): Promise<$Ecs20140526.DescribeRegionsResponse> {
        const credentialsConfig = new Config({
            type: 'oidc_role_arn',
            // RAM角色名稱ARN,可以通過環境變數ALIBABA_CLOUD_ROLE_ARN設定roleArn
            roleArn: '<RoleArn>',
            // OIDC供應商ARN,可以通過環境變數ALIBABA_CLOUD_OIDC_PROVIDER_ARN設定oidcProviderArn
            oidcProviderArn: '<OidcProviderArn>',
            // OIDC Token檔案路徑,可以通過環境變數ALIBABA_CLOUD_OIDC_TOKEN_FILE設定oidcTokenFilePath
            oidcTokenFilePath: '<OidcTokenFilePath>',
            // 自訂角色會話名稱,可以通過環境變數ALIBABA_CLOUD_ROLE_SESSION_NAME設定roleSessionName
            roleSessionName: '<RoleSessionName>',
            // 設定更小的權限原則,非必填。樣本值:{"Statement": [{"Action": ["*"],"Effect": "Allow","Resource": ["*"]}],"Version":"1"}
            policy: '<Policy>',
            // 設定session到期時間
            roleSessionExpiration: 3600,
        });
        const credentialClient = new Credential(credentialsConfig);
        let config = new $OpenApi.Config({
            credential: credentialClient, // 使用Credentials配置憑證。
            endpoint: 'ecs.cn-hangzhou.aliyuncs.com', // 配置雲產品服務接入地址(endpoint)。
        });
        let client = new Ecs20140526(config);
        let describeRegionsRequest = new $Ecs20140526.DescribeRegionsRequest({});
        let runtime = new $Util.RuntimeOptions({});
        return await client.describeRegionsWithOptions(describeRegionsRequest, runtime);
    }
}
const response = Client.main();
response.then(res => {
    console.log(res.body?.regions);
});

方式七:使用URI憑據

通過封裝STS服務並對外暴露服務的URI,外部服務能夠通過該URI擷取STS Token,從而有效降低AK等敏感資訊的暴露風險。Credentials工具支援通過訪問您所提供的URI來擷取STS Token,並將該STS Token作為訪問憑據。通過此方式擷取的憑據支援自動重新整理,詳情請參見Session類型憑據自動重新整理機制

const Credential = require('@alicloud/credentials');
const config = new Credential.Config({
    type: 'credentials_uri',
    // 擷取憑證的 URI,格式為http://local_or_remote_uri/,可以通過環境變數ALIBABA_CLOUD_CREDENTIALS_URI設定credentialsUri
    credentialsURI: '<CredentialsUri>',
});
const credentialClient = new Credential(config);
import Credential, { Config } from '@alicloud/credentials';
const credentialsConfig = new Config({
    type: 'credentials_uri',
    // 擷取憑證的 URI,格式為http://local_or_remote_uri/,可以通過環境變數ALIBABA_CLOUD_CREDENTIALS_URI設定credentialsUri
    credentialsURI: '<CredentialsUri>',
});
const credentialClient = new Credential(credentialsConfig);

該地址必須滿足如下條件:

  • 響應狀態代碼為200

  • 響應體為如下的結構

    {
      "Code": "Success",
      "AccessKeySecret": "AccessKeySecret",
      "AccessKeyId": "AccessKeyId",
      "Expiration": "2021-09-26T03:46:38Z",
      "SecurityToken": "SecurityToken"
    }

介面調用方法

本樣本以調用Elastic Compute Service的DescribeRegions介面為例,因此需先安裝ECS SDK

const Ecs20140526 = require('@alicloud/ecs20140526');
const OpenApi = require('@alicloud/openapi-client');
const Util = require('@alicloud/tea-util');
const Credential = require('@alicloud/credentials');
async function main() {
    const credentialsConfig = new Credential.Config({
        // 憑證類型。
        type: 'credentials_uri',
        // 擷取憑證的 URI,格式為http://local_or_remote_uri/,可以通過環境變數ALIBABA_CLOUD_CREDENTIALS_URI設定credentialsUri
        credentialsURI: '<CredentialsUri>',
    });
    const credentialClient = new Credential.default(credentialsConfig);
    const ecsConfig = new OpenApi.Config({
        endpoint: 'ecs.cn-hangzhou.aliyuncs.com', // 配置雲產品服務接入地址(endpoint)。
        credential: credentialClient, // 使用Credentials配置憑證。
    });
    const ecsClient = new Ecs20140526.default(ecsConfig);
    const describeRegionsRequest = new Ecs20140526.DescribeRegionsRequest();
    const runtime = new Util.RuntimeOptions();
    // 調用DescribeRegions介面並獲得響應。
    const response = ecsClient.describeRegionsWithOptions(describeRegionsRequest, runtime);
    console.log((await response).body.regions);
}
main().catch(console.error);
import Ecs20140526, * as $Ecs20140526 from '@alicloud/ecs20140526';
import Credential, { Config } from '@alicloud/credentials';
import OpenApi, * as $OpenApi from '@alicloud/openapi-client';
import Util, * as $Util from '@alicloud/tea-util';
export default class Client {
    static async main(): Promise<$Ecs20140526.DescribeRegionsResponse> {
        let credentialsConfig = new Config({
            type: 'credentials_uri',
            // 擷取憑證的 URI,格式為http://local_or_remote_uri/,可以通過環境變數ALIBABA_CLOUD_CREDENTIALS_URI設定credentialsUri
            credentialsURI: '<CredentialsUri>',
        });
        let credentialClient = new Credential(credentialsConfig);
        let config = new $OpenApi.Config({
            credential: credentialClient, // 使用Credentials配置憑證。
            endpoint: 'ecs.cn-hangzhou.aliyuncs.com', // 配置雲產品服務接入地址(endpoint)。
        });
        let client = new Ecs20140526(config);
        let describeRegionsRequest = new $Ecs20140526.DescribeRegionsRequest({});
        let runtime = new $Util.RuntimeOptions({});
        return await client.describeRegionsWithOptions(describeRegionsRequest, runtime);
    }
}
const response = Client.main();
response.then(res => {
    console.log(res.body?.regions);
});

方式八:使用Bearer Token

目前只有Cloud Call CenterCCC這款產品支援Bearer Token。

const Credential = require('@alicloud/credentials');
const config = new Credential.Config({
    type: 'bearer',
    // 填入您的Bearer Token
    bearerToken: '<BearerToken>',
});
const credentialClient = new Credential(config);
import Credential, { Config } from '@alicloud/credentials';
const credentialsConfig = new Config({
    type: 'bearer',
    // 填入您的Bearer Token
    bearerToken: '<BearerToken>',
});
const credentialClient = new Credential(credentialsConfig);

介面調用方法

本樣本以調用話務中心CCC的GetInstance介面為例,因此需先安裝CCC SDK

const CCC20200701 = require('@alicloud/ccc20200701');
const OpenApi = require('@alicloud/openapi-client');
const Util = require('@alicloud/tea-util');
const Credential = require('@alicloud/credentials');
async function main() {
    let credentialsConfig = new Credential.Config({
        // 憑證類型。
        type: 'bearer',
        // 填入您的Bearer Token
        bearerToken: '<BearerToken>',
    });
    let credentialClient = new Credential.default(credentialsConfig);
    let config = new OpenApi.Config({
        endpoint: 'ccc.cn-shanghai.aliyuncs.com',
        credential: credentialClient
    });
    let client = new CCC20200701.default(config);
    let getInstanceRequest = new CCC20200701.GetInstanceRequest({
        instanceId: 'ccc-test',
    });
    let runtime = new Util.RuntimeOptions({});
    let response = client.getInstanceWithOptions(getInstanceRequest, runtime);
    console.log((await response).body);
}
main().catch(console.error);
import ccc20200701, * as $ccc20200701 from '@alicloud/ccc20200701';
import Credential, { Config } from '@alicloud/credentials';
import OpenApi, * as $OpenApi from '@alicloud/openapi-client';
import Util, * as $Util from '@alicloud/tea-util';
export default class Client {
    static async main(): Promise<$ccc20200701.GetInstanceResponse> {
        let credentialsConfig = new Config({
            type: 'bearer',
            // 填入您的Bearer Token
            bearerToken: '<BearerToken>',
        });
        let credentialClient = new Credential(credentialsConfig);
        let config = new $OpenApi.Config({
            credential: credentialClient, // 使用Credentials配置憑證。
            endpoint: 'ccc.cn-shanghai.aliyuncs.com', // 配置雲產品服務接入地址(endpoint)。
        });
        let client = new ccc20200701(config);
        let GetInstanceRequest = new $ccc20200701.GetInstanceRequest({
            instanceId: 'ccc-test',
        });
        let runtime = new $Util.RuntimeOptions({});
        return await client.getInstanceWithOptions(GetInstanceRequest, runtime);
    }
}
let response = Client.main();
response.then(res => {
    console.log(res.body?.regions);
});

預設憑據鏈

當您的程式開發環境和生產環境採用不同的憑據類型,常見做法是在代碼中擷取當前環境資訊,編寫擷取不同憑據的分支代碼。藉助Credentials工具的預設憑據鏈,您可以用同一套代碼,通過程式之外的配置來控制不同環境下的憑據擷取方式。當您在不傳入參數的情況下,直接使用new Credential()初始化憑據用戶端時,阿里雲SDK將會嘗試按照如下順序尋找相關憑據資訊。

1. 使用環境變數

如果未找到系統屬性中的憑據資訊,Credentials工具會繼續檢查環境變數。

  • 如果 ALIBABA_CLOUD_ACCESS_KEY_ID ALIBABA_CLOUD_ACCESS_KEY_SECRET 均存在且非空,則使用它們作為預設憑據。

  • 如果同時設定了 ALIBABA_CLOUD_ACCESS_KEY_ID、ALIBABA_CLOUD_ACCESS_KEY_SECRET ALIBABA_CLOUD_SECURITY_TOKEN,則使用STS Token作為預設憑據。

2. 使用OIDC RAM角色

如果仍未擷取到憑據資訊,Credentials工具會檢查以下與OIDC RAM角色相關的環境變數:

  • ALIBABA_CLOUD_ROLE_ARN:RAM角色名稱ARN。

  • ALIBABA_CLOUD_OIDC_PROVIDER_ARN:OIDC供應商ARN。

  • ALIBABA_CLOUD_OIDC_TOKEN_FILE:OIDC Token檔案路徑。

如果以上三個環境變數均存在且非空,Credentials將會使用變數內容調用STS服務的AssumeRoleWithOIDC介面換取STS Token作為預設憑據。

3. 使用config.json設定檔

如果仍未擷取到憑據資訊,Credentials工具會嘗試從預設路徑載入config.json設定檔,並擷取指定的憑據作為預設憑據。該檔案的預設完整路徑如下:

  • Linux/Mac:~/.aliyun/config.json

  • Windows: C:\Users\USER_NAME\.aliyun\config.json

如果您需要通過此方式配置憑據,您可以使用阿里雲CLI工具配置憑據,或手動在相應路徑下建立config.json設定檔。內容格式樣本如下:

{
  "current": "<PROFILE_NAME>",
  "profiles": [
    {
      "name": "<PROFILE_NAME>",
      "mode": "AK",
      "access_key_id": "<ALIBABA_CLOUD_ACCESS_KEY_ID>",
      "access_key_secret": "<ALIBABA_CLOUD_ACCESS_KEY_SECRET>"
    },
    {
      "name": "<PROFILE_NAME1>",
      "mode": "StsToken",
      "access_key_id": "<ALIBABA_CLOUD_ACCESS_KEY_ID>",
      "access_key_secret": "<ALIBABA_CLOUD_ACCESS_KEY_SECRET>",
      "sts_token": "<SECURITY_TOKEN>"
    },
    {
      "name":"<PROFILE_NAME2>",
      "mode":"RamRoleArn",
      "access_key_id":"<ALIBABA_CLOUD_ACCESS_KEY_ID>",
      "access_key_secret":"<ALIBABA_CLOUD_ACCESS_KEY_SECRET>",
      "ram_role_arn":"<ROLE_ARN>",
      "ram_session_name":"<ROLE_SESSION_NAME>",
      "expired_seconds":3600
    },
    {
      "name":"<PROFILE_NAME3>",
      "mode":"EcsRamRole",
      "ram_role_name":"<RAM_ROLE_ARN>"
    },
    {
      "name":"<PROFILE_NAME4>",
      "mode":"OIDC",
      "oidc_provider_arn":"<OIDC_PROVIDER_ARN>",
      "oidc_token_file":"<OIDC_TOKEN_FILE>",
      "ram_role_arn":"<ROLE_ARN>",
      "ram_session_name":"<ROLE_SESSION_NAME>",
      "expired_seconds":3600
    },
    {
      "name":"<PROFILE_NAME5>",
      "mode":"ChainableRamRoleArn",
      "source_profile":"<PROFILE_NAME>",
      "ram_role_arn":"<ROLE_ARN>",
      "ram_session_name":"<ROLE_SESSION_NAME>",
      "expired_seconds":3600
    }
  ]
}

參數名稱

參數介紹

current

指定憑據名稱以擷取相應的憑據配置資訊,其值為profiles中參數name的值。預設情況下,系統優先使用環境變數 ALIBABA_CLOUD_PROFILE 指定的憑據名稱;若該環境變數未配置,則將使用current指定的憑據名稱。

profiles

憑據資訊集合。通過參數mode指定憑據的類型:

  • AK:使用使用者的AccessKey作為憑據資訊;

  • StsToken:使用STS Token作為憑據資訊;

  • RamRoleArn:通過RAM使用者扮演RAM角色擷取憑證資訊。

  • EcsRamRole:通過執行個體中繼資料擷取憑據資訊;

  • OIDC:通過OIDC身份供應商ARN、OIDC Token和RAM角色ARN擷取憑據資訊;

  • ChainableRamRoleArn:採用角色鏈的方式,通過source_profile指定profiles中其他憑據的名稱,以重新擷取新的憑據資訊。

4. 使用ECS執行個體RAM角色

如果未找到更高優先順序的憑據資訊,Credentials會嘗試通過ECS執行個體綁定的RAM角色擷取憑據。預設情況下,Credentials會使用加固模式(IMDSv2)訪問ECS的中繼資料服務(Meta Data Server),以擷取ECS執行個體RAM角色的STS Token作為預設憑據資訊。程式會自動訪問ECS的中繼資料服務拿到RoleName資訊,再去擷取憑證,也就是兩次請求。若想減少一次請求,可以直接在環境變數中配置 ALIBABA_CLOUD_ECS_METADATA 來指定執行個體RAM角色名稱。在使用加固模式時若發生異常,將使用普通模式兜底來擷取訪問憑據。您也可以通過設定環境變數ALIBABA_CLOUD_IMDSV1_DISABLE,執行不同的異常處理邏輯:

  1. 當值為false時,會使用普通模式繼續擷取訪問憑據。

  2. 當值為true時,表示只能使用加固模式擷取訪問憑據,會拋出異常。

服務端是否支援IMDSv2,取決於您在伺服器的配置。

另外,您可以通過配置環境變數ALIBABA_CLOUD_ECS_METADATA_DISABLED=true來關閉ECS中繼資料的憑證訪問。

說明

5. 使用Credentials工具URI

如果仍未擷取到憑據資訊,Credentials工具會檢查環境變數 ALIBABA_CLOUD_CREDENTIALS_URI,如果該變數存在且指向一個有效URI地址,Credentials通過訪問該URI來擷取STS Token作為預設憑據。

Session類型憑據自動重新整理機制

Session類型憑據包含ram_role_arnecs_ram_roleoidc_role_arn以及credentials_uri,該類型憑據在Credentials工具中內建了憑據自動重新整理機制。當憑據用戶端首次擷取憑據後,Credentials工具會將擷取的憑據資訊儲存至緩衝中。在後續使用過程中,同一憑據用戶端執行個體將自動從緩衝中提取憑據;若緩衝中的憑據資訊已到期,則憑據用戶端執行個體將重新擷取憑據,並更新緩衝中的值。

說明

對於ecs_ram_role類型憑據,Credentials工具將會在緩衝中的值到期前15分鐘進行提前重新整理。

下面將採用單例模式建立憑據用戶端,通過多個時間段擷取憑據來驗證憑據重新整理機制,並通過調用OpenAPI確保所擷取的憑據處於可用狀態。

const Credential = require('@alicloud/credentials');
const Ecs20140526 = require('@alicloud/ecs20140526');
const { Config } = require('@alicloud/openapi-client');
const { RuntimeOptions } = require('@alicloud/tea-util');
// 擷取環境變數
const accessKeyId = process.env.ALIBABA_CLOUD_ACCESS_KEY_ID;
const accessKeySecret = process.env.ALIBABA_CLOUD_ACCESS_KEY_SECRET;
const roleArn = process.env.ALIBABA_CLOUD_ROLE_ARN;
/**
 * Credential 單例類,用於管理阿里雲憑證執行個體。
 */
class CredentialClient {
    constructor() {
        if (!CredentialClient.instance) {
            var credentialsConfig = new Credential.Config({
                type: 'ram_role_arn',
                accessKeyId: accessKeyId,
                accessKeySecret: accessKeySecret,
                roleArn: roleArn,
                roleSessionName: 'RoleSessionNameTest',
                roleSessionExpiration: 3600,
            });
            this.credentialsClient = new Credential.default(credentialsConfig);
            CredentialClient.instance = this;
        }
        return CredentialClient.instance;
    }
    static getInstance() {
        return new CredentialClient().credentialsClient;
    }
}
/**
 * ECS Client 單例類,用於管理 ECS 用戶端執行個體。
 */
class EcsClient {
    constructor(credentialClient) {
        if (!EcsClient.instance) {
            const config = new Config({
                endpoint: 'ecs.cn-hangzhou.aliyuncs.com',
                credential: credentialClient
            });
            this.ecsClient = new Ecs20140526.default(config);
            EcsClient.instance = this;
        }
        return EcsClient.instance;
    }
    static getInstance(credentialClient) {
        return new EcsClient(credentialClient).ecsClient;
    }
}
/**
 * 執行任務邏輯
 */
async function executeTask() {
    try {
        const credentialClient = CredentialClient.getInstance();
        const credential = await credentialClient.getCredential();
        console.log(new Date());
        console.log(`AK ID: ${credential.accessKeyId}`);
        console.log(`AK Secret: ${credential.accessKeySecret}`);
        console.log(`STS Token: ${credential.securityToken}`);
        // 這裡以調用ECS介面為例驗證憑據是否可用,您可根據實際情況修改
        const ecsClient = EcsClient.getInstance(credentialClient);
        const request = new Ecs20140526.DescribeRegionsRequest();
        const runtime = new RuntimeOptions({});
        const response = await ecsClient.describeRegionsWithOptions(request, runtime);
        console.log(`Invoke result: ${response.statusCode}`);
    } catch (error) {
        throw new Error(`ECS client execution failed: ${error.message}`, { cause: error });
    }
}
/**
 * 使用定時器調度任務執行
 */
function scheduleTasks() {
    // 立即執行一次
    executeTask();
    // 設定後續任務順延強制
    setTimeout(executeTask, 600 * 1000); // 第二次:600秒後
    setTimeout(executeTask, 4200 * 1000); // 第三次:4200秒後
    setTimeout(executeTask, 4300 * 1000); // 第四次:4300秒後
}
// 啟動任務調度
scheduleTasks();
import Credential, { Config as CredentialsConfig }  from '@alicloud/credentials';
import Ecs20140526, * as $Ecs20140526 from '@alicloud/ecs20140526';
import { Config } from '@alicloud/openapi-client';
import { RuntimeOptions } from '@alicloud/tea-util';
// 擷取環境變數
const accessKeyId: string | undefined = process.env.ALIBABA_CLOUD_ACCESS_KEY_ID;
const accessKeySecret: string | undefined = process.env.ALIBABA_CLOUD_ACCESS_KEY_SECRET;
const roleArn: string | undefined = process.env.ALIBABA_CLOUD_ROLE_ARN;
if (!accessKeyId || !accessKeySecret || !roleArn) {
    throw new Error('Missing required environment variables.');
}
/**
 * Credential 單例類,用於管理阿里雲憑證執行個體。
 */
class CredentialClient {
    private static instance: CredentialClient;
    private readonly credentialsClient: InstanceType<typeof Credential>;
    private constructor() {
        const credentialsConfig = new CredentialsConfig({
            type: 'ram_role_arn',
            accessKeyId,
            accessKeySecret,
            roleArn,
            roleSessionName: 'RoleSessionNameTest',
            roleSessionExpiration: 3600,
        });
        this.credentialsClient = new Credential(credentialsConfig);
    }
    static getInstance(): InstanceType<typeof Credential> {
        if (!CredentialClient.instance) {
            CredentialClient.instance = new CredentialClient();
        }
        return CredentialClient.instance.credentialsClient;
    }
}
/**
 * ECS Client 單例類,用於管理 ECS 用戶端執行個體。
 */
class EcsClient {
    private static instance: EcsClient;
    private readonly ecsClient: InstanceType<typeof Ecs20140526>;
    private constructor(credentialClient: InstanceType<typeof Credential>) {
        const config = new Config({
            endpoint: 'ecs.cn-hangzhou.aliyuncs.com',
            credential: credentialClient
        });
        this.ecsClient = new Ecs20140526(config);
    }
    static getInstance(credentialClient: InstanceType<typeof Credential>): InstanceType<typeof Ecs20140526> {
        if (!EcsClient.instance) {
            EcsClient.instance = new EcsClient(credentialClient);
        }
        return EcsClient.instance.ecsClient;
    }
}
/**
 * 執行任務邏輯
 */
async function executeTask(): Promise<void> {
    try {
        const credentialClient = CredentialClient.getInstance();
        const credential = await credentialClient.getCredential();
        console.log(new Date());
        console.log(`AK ID: ${credential.accessKeyId}`);
        console.log(`AK Secret: ${credential.accessKeySecret}`);
        console.log(`STS Token: ${credential.securityToken}`);
        // 這裡以調用ECS介面為例驗證憑據是否可用,您可根據實際情況修改
        const ecsClient = EcsClient.getInstance(credentialClient);
        const request = new $Ecs20140526.DescribeRegionsRequest();
        const runtime = new RuntimeOptions({});
        const response = await ecsClient.describeRegionsWithOptions(request, runtime);
        console.log(`Invoke result: ${response.statusCode}`);
    } catch (error) {
        throw new Error(`ECS client execution failed: ${error}`);
    }
}
/**
 * 使用定時器調度任務執行
 */
function scheduleTasks(): void {
    // 立即執行一次
    executeTask();
    // 設定後續任務順延強制
    setTimeout(executeTask, 600 * 1000); // 第二次:600秒後
    setTimeout(executeTask, 4200 * 1000); // 第三次:4200秒後
    setTimeout(executeTask, 4300 * 1000); // 第四次:4300秒後
}
// 啟動任務調度
scheduleTasks();
2025-05-28T09:22:29.584Z
AK ID: STS.NVS9xxx7DRbao
AK Secret: 9SoQxxxmVjVsED9ad47rcgMaw5XyQyXx
STS Token:
CAISyQJ1q6Ft5B2yfSjIr5Xmcu/irrxq0pWvU0PZhvVtS7hovafKjTz2IHhMeXZoA+4YsPw2mmFW6/sdlrpJTJtIfkHfdsp36LJe9A6dbpHd4xc1LGed0s/LI3OaLjKm9u2wCryLYbGwU/OpbE++5U0X6LDmdDKkckW40JmS8/BOZcgWWQ/KB1gvRq
0hRG1YpdQdKGHa0xxxWg0/ks0aH1war1bBL+tqofMP9MfMBZskvD42Hu8VtbbfE3SJq7BxHybx71qQs+02c5onAXAELvUvYa7OKo4MyCVBjBKEhALNBoeL7kfBobmFAAkgwYnynVMMisES3LOiIqKOsk1MdI9Cywly2y
vfiZZ1prmk1pV68xxxczc4yvhD2nuNe7rmc9Z3/JHusVmo7LiTxqAARdkoKCeYBvLk0ZFWccCiM0ZvdnRtv0VDOUfD1zQELQGL+xB5NrBmdzq2ePjFJbrkBGmy5EXD714jknyzM4lFic2dUQMi14NCHMVDVjGAf0qUs
F+PQW58jGb32fmFxxxTXOx82sdRQqW0/vTd2KQmIAA=
Invoke result: 200
2025-05-28T09:32:28.137Z
AK ID: STS.NVS9xxx7DRbao
AK Secret: 9SoQxxxmVjVsED9ad47rcgMaw5XyQyXx
STS Token:
CAISyQJ1q6Ft5B2yfSjIr5Xmcu/irrxq0pWvU0PZhvVtS7hovafKjTz2IHhMeXZoA+4YsPw2mmFW6/sdlrpJTJtIfkHfdsp36LJe9A6dbpHd4xc1LGed0s/LI3OaLjKm9u2wCryLYbGwU/OpbE++5U0X6LDmdDKkckW40JmS8/BOZcgWWQ/KB1gvRq
0hRG1YpdQdKGHa0xxxWg0/ks0aH1war1bBL+tqofMP9MfMBZskvD42Hu8VtbbfE3SJq7BxHybx71qQs+02c5onAXAELvUvYa7OKo4MyCVBjBKEhALNBoeL7kfBobmFAAkgwYnynVMMisES3LOiIqKOsk1MdI9Cywly2y
vfiZZ1prmk1pV68xxxczc4yvhD2nuNe7rmc9Z3/JHusVmo7LiTxqAARdkoKCeYBvLk0ZFWccCiM0ZvdnRtv0VDOUfD1zQELQGL+xB5NrBmdzq2ePjFJbrkBGmy5EXD714jknyzM4lFic2dUQMi14NCHMVDVjGAf0qUs
F+PQW58jGb32fmFxxxTXOx82sdRQqW0/vTd2KQmIAA=
Invoke result: 200
2025-05-28T10:32:29.771Z
AK ID: STS.NVuaxxxLFiPw8
AK Secret: 5dsoxxxpA5pCzfrek4KforS8MnJ6qHR9
STS Token:
CAISyQJ1q6Ft5B2yfSjIr5XAKsjd241w4PqgY1P2gDUvb8NqhpXc2jz2IHhMeXZoA+4YsPw2mmFW6/sdlrpJTJtIfkHfdsp36LJe9A6dbpHd4yVKL2Gd0s/LI3OaLjKm9u2wCryLYbGwU/OpbE++5U0X6LDmdDKkckW40JmS8/BOZcgWWQ/KB1gvRq
0hRG1YpdQdKGHa0xxxWg0/ks0aH1war1bBL+tqofMP9MfMBZskvD42Hu8VtbbfE3SJq7BxHybx71qQs+02c5onAXAELvUvYa7OKo4MyCVBjBKEhALNBoeL7kfBobmFAAkgwYnynVMMisES3LOjIqKOsk+Mdk9CiWv2y
vfiZZ1prmk1pV68xxxczc4yvhD2nuNe7rmc9Z3/KpUoQEo7LiTxqAAUyV7F+kpLHRG/yHw3JaVz14hqSj2hmxxkwgczUWIkpBLKHLeW0iI3sp2LNQO6iEAImLpSE0nRVBbcutIqxEuFzAs607jgOjHakTF7UZNoKVV
wb42xR4s4ThGd2PxxxqoUsrKfCq5lHiUiDq6L1VIAA=
Invoke result: 200
2025-05-28T10:34:08.130Z
AK ID: STS.NVuaxxxLFiPw8
AK Secret: 5dsoxxxpA5pCzfrek4KforS8MnJ6qHR9
STS Token:
CAISyQJ1q6Ft5B2yfSjIr5XAKsjd241w4PqgY1P2gDUvb8NqhpXc2jz2IHhMeXZoA+4YsPw2mmFW6/sdlrpJTJtIfkHfdsp36LJe9A6dbpHd4yVKL2Gd0s/LI3OaLjKm9u2wCryLYbGwU/OpbE++5U0X6LDmdDKkckW40JmS8/BOZcgWWQ/KB1gvRq
0hRG1YpdQdKGHa0xxxWg0/ks0aH1war1bBL+tqofMP9MfMBZskvD42Hu8VtbbfE3SJq7BxHybx71qQs+02c5onAXAELvUvYa7OKo4MyCVBjBKEhALNBoeL7kfBobmFAAkgwYnynVMMisES3LOjIqKOsk+Mdk9CiWv2y
vfiZZ1prmk1pV68xxxczc4yvhD2nuNe7rmc9Z3/KpUoQEo7LiTxqAAUyV7F+kpLHRG/yHw3JaVz14hqSj2hmxxkwgczUWIkpBLKHLeW0iI3sp2LNQO6iEAImLpSE0nRVBbcutIqxEuFzAs607jgOjHakTF7UZNoKVV
wb42xR4s4ThGd2PxxxqoUsrKfCq5lHiUiDq6L1VIAA=
Invoke result: 200

根據日誌顯示結果進行分析:

  • 在第一次調用時,由於未緩衝憑據資訊,系統根據配置擷取憑據資訊。擷取到憑據後,憑據資訊被儲存在緩衝中。

  • 第二次調用所使用的憑據資訊與第一次相同,表明第二次調用是從緩衝中提取的憑據資訊。

  • 第三次調用時,由於憑據的到期時間(RoleSessionExpiration)被設定為3600秒,而第三次調用發生在第一次調用之後的4200秒,此時緩衝中的憑據已到期。因此,SDK依據自動重新整理機制重新擷取了新的憑據資訊,並將新擷取的憑據資訊再次儲存於緩衝中。

  • 第四次調用所使用的憑據資訊與第三次重新擷取的憑據資訊一致,這表明緩衝中的憑據在到期後已被更新為新的憑據。

相關文檔