Node.js如何配置访问凭证

重要

本文中含有需要您注意的重要提示信息,忽略该信息可能对您的业务造成影响,请务必仔细阅读。

使用Node.js SDK发起OSS请求,您需要配置访问凭证。阿里云服务会通过访问凭证验证您的身份信息和访问权限。您可以根据使用场景对认证和授权的要求,选择不同的方式提供凭证。

前提条件

在配置访问凭证前,您需要安装OSS Node.js SDK。详情请参见安装

初始化凭证提供者

凭证提供者选型

OSS支持多种方式初始化凭证提供者,您可以根据使用场景对认证和授权的要求,选择对应的方式初始化凭证提供者。

凭证提供者初始化方式

适用场景

是否需要提供前置的AKSTS Token

底层实现基于的凭证

凭证有效期

凭证轮转或刷新方式

方式一:使用AK

部署运行在安全、稳定且不易受外部攻击的环境的应用程序,无需频繁轮转凭证就可以长期访问云服务

AK

长期

手动轮转

方式二:使用STS Token

部署运行在不可信的环境的应用程序,希望能控制访问的有效期、权限

STS Token

临时

手动刷新

方式三:使用RAMRoleARN

需要授权访问云服务,例如跨阿里云账号访问云服务的应用程序

STS Token

临时

自动刷新

方式四:通过ECS实例元数据普通模式获取RAM角色

部署运行在阿里云的ECS实例、ECI实例、容器服务Kubernetes版的Worker节点中的应用程序

STS Token

临时

自动刷新

方式五:使用OIDCRoleArn

部署运行在阿里云的容器服务Kubernetes版的Worker节点中的不可信应用程序

STS Token

临时

自动刷新

方式六:使用CredentialsURI

需要通过外部系统获取访问凭证的应用程序

STS Token

临时

自动刷新

方式一:使用AK

如果您的应用程序部署运行在安全、稳定且不易受外部攻击的环境中,需要长期访问您的OSS,且不能频繁轮转凭证时,您可以使用阿里云主账号或RAM用户的AK(Access Key ID、Access Key Secret)初始化凭证提供者。需要注意的是,该方式需要您手动维护一个AK,存在安全性风险和维护复杂度增加的风险。如何获取AK,请参见CreateAccessKey - 创建主账号或RAM用户访问密钥

警告

阿里云账号拥有资源的全部权限,AK一旦泄露,会给系统带来巨大风险,不建议使用。推荐使用最小化授权的RAM用户的AK。

  1. 设置环境变量。

    Mac OS X/Linux/Unix

    export ALIBABA_CLOUD_ACCESS_KEY_ID=<ALIBABA_CLOUD_ACCESS_KEY_ID>
    export ALIBABA_CLOUD_ACCESS_KEY_SECRET=<ALIBABA_CLOUD_ACCESS_KEY_SECRET>

    Windows

    set ALIBABA_CLOUD_ACCESS_KEY_ID=<ALIBABA_CLOUD_ACCESS_KEY_ID>
    set ALIBABA_CLOUD_ACCESS_KEY_SECRET=<ALIBABA_CLOUD_ACCESS_KEY_SECRET>
  2. 使用AK完成客户端初始化。

    const OSS = require("ali-oss");
    
    // 初始化OSS
    const client = new OSS({
      // 从环境变量中获取AccessKey ID的值
      accessKeyId: process.env.ALIBABA_CLOUD_ACCESS_KEY_ID,
      // 从环境变量中获取AccessKey Secret的值
      accessKeySecret: process.env.ALIBABA_CLOUD_ACCESS_KEY_SECRET
    });
    
    // listBuckets
    const buckets = await client.listBuckets();
    console.log(buckets);
    

方式二:使用STS Token

以一个RAM用户的身份调用STS服务的AssumeRole - 获取扮演角色的临时身份凭证接口,设置Token的最大过期时间,即可换取到临时凭证STS Token。

  1. 设置环境变量。

    Mac OS X/Linux/Unix

    export ALIBABA_CLOUD_ACCESS_KEY_ID=<ALIBABA_CLOUD_ACCESS_KEY_ID>
    export ALIBABA_CLOUD_ACCESS_KEY_SECRET=<ALIBABA_CLOUD_ACCESS_KEY_SECRET>
    export ALIBABA_CLOUD_SECURITY_TOKEN=<ALIBABA_CLOUD_SECURITY_TOKEN>

    Windows

    set ALIBABA_CLOUD_ACCESS_KEY_ID=<ALIBABA_CLOUD_ACCESS_KEY_ID>
    set ALIBABA_CLOUD_ACCESS_KEY_SECRET=<ALIBABA_CLOUD_ACCESS_KEY_SECRET>
    set ALIBABA_CLOUD_SECURITY_TOKEN=<ALIBABA_CLOUD_SECURITY_TOKEN>
  2. 使用临时凭证完成客户端初始化。

    const OSS = require("ali-oss");
    
    // 初始化OSS
    const client = new OSS({
      // 从环境变量中获取AccessKey ID的值
      accessKeyId: process.env.ALIBABA_CLOUD_ACCESS_KEY_ID,
      // 从环境变量中获取AccessKey Secret的值
      accessKeySecret: process.env.ALIBABA_CLOUD_ACCESS_KEY_SECRET,
      // 从环境变量中获取STS Token的值
      stsToken: process.env.ALIBABA_CLOUD_SECURITY_TOKEN
    });
    
    // listBuckets
    const buckets = await client.listBuckets();
    console.log(buckets);

方式三:使用RAMRoleARN

该方式底层实现是STS Token。通过指定RAM角色的ARN(Alibabacloud Resource Name),Credentials工具可以帮助开发者前往STS换取STS Token。您也可以通过为policy赋值来限制RAM角色到一个更小的权限集合。

使用AKRAMRoleARN初始化Credentials,完成客户端初始化。

const Credential = require("@alicloud/credentials");
const OSS = require("ali-oss");

// 使用RamRoleArn初始化Credentials Client。
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 credential = await credentialClient.getCredential();

// 初始化OSS
const client = new OSS({
  accessKeyId:credential.accessKeyId,
  accessKeySecret: credential.accessKeySecret,
  stsToken: credential.securityToken,
  refreshSTSTokenInterval: 0, // 由Credential控制accessKeyId、accessKeySecret和stsToken值的更新
  refreshSTSToken: async () => {
    const { accessKeyId, accessKeySecret, securityToken } = await credentialClient.getCredential();
    return {
      accessKeyId,
      accessKeySecret,
      stsToken: securityToken,
    };
  }
});

// listBuckets
const buckets = await client.listBuckets();
console.log( buckets);

方式四:通过ECS实例元数据普通模式获取RAM角色

该方式底层实现是STS Token。Credentials工具会自动获取ECS实例绑定的RAM角色,调用ECS的元数据服务(Meta Data Server)换取STS Token,完成凭据客户端初始化。通过Credentials工具读取STS Token,完成客户端初始化。

const Credential = require("@alicloud/credentials");
const OSS = require("ali-oss");

// 使用RamRoleArn初始化Credentials Client。
const credentialsConfig = new Credential.Config({
  // 凭证类型。
  type: "ecs_ram_role",
  // 选填,该ECS角色的角色名称,不填会自动获取,但是建议加上以减少请求次数,可以通过环境变量ALIBABA_CLOUD_ECS_METADATA设置roleName
  roleName: '<RoleName>'
});
const credentialClient = new Credential.default(credentialsConfig);

const { accessKeyId, accessKeySecret, securityToken } = await credentialClient.getCredential();

// 初始化OSS Client
const client = new OSS({
  accessKeyId,
  accessKeySecret,
  stsToken: securityToken,
  refreshSTSTokenInterval: 0, // 由Credential控制accessKeyId、accessKeySecret和stsToken值的更新
  refreshSTSToken: async () => {
    const { accessKeyId, accessKeySecret, securityToken } = await credentialClient.getCredential();
    
    return {
      accessKeyId,
      accessKeySecret,
      stsToken: securityToken,
    };
  }
});

// listBuckets
const buckets = await client.listBuckets();
console.log(buckets);

方式五:使用OIDCRoleArn

在容器服务 Kubernetes 版中设置了Worker节点RAM角色后,对应节点内的Pod中的应用也就可以像ECS上部署的应用一样,通过元数据服务(Meta Data Server)获取关联角色的STS Token。但如果容器集群上部署的是不可信的应用(比如部署您的客户提交的应用,代码也没有对您开放),您可能并不希望它们能通过元数据服务获取Worker节点关联实例RAM角色的STS Token。为了避免影响云上资源的安全,同时又能让这些不可信的应用安全地获取所需的 STS Token,实现应用级别的权限最小化,您可以使用RRSA(RAM Roles for Service Account)功能。阿里云容器集群会为不同的应用Pod创建和挂载相应的服务账户OIDC Token文件,并将相关配置信息注入到环境变量中,Credentials工具通过获取环境变量的配置信息,调用STS服务的AssumeRoleWithOIDC - OIDC角色SSO时获取扮演角色的临时身份凭证接口换取绑定角色的STS Token。详情请参见通过RRSA配置ServiceAccountRAM权限实现Pod权限隔离

配置OIDCRAM角色作为访问凭证,完成客户端初始化。

const OSS = require("ali-oss");
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);
const { accessKeyId, accessKeySecret, securityToken } = await credentialClient.getCredential();
const client = new OSS({
  accessKeyId,
  accessKeySecret,
  stsToken: securityToken,
  refreshSTSTokenInterval: 0, // 由Credential控制accessKeyId、accessKeySecret和stsToken值的更新
  refreshSTSToken: async () => {
    const { accessKeyId, accessKeySecret, securityToken } = await credentialClient.getCredential();
    
    return {
      accessKeyId,
      accessKeySecret,
      stsToken: securityToken,
    };
  }
});
const buckets = await client.listBuckets();

console.log(buckets);

方式六:使用CredentialsURI

如果您的应用程序需要通过外部系统获取阿里云凭证,从而实现灵活的凭证管理和无密钥访问,您可以使用CredentialsURI初始化凭证提供者。该方式底层实现是STS Token。Credentials工具通过您提供的URI获取STS Token,完成凭证客户端初始化。该方式无需您提供一个AKSTS Token,消除了手动维护AKSTS Token的风险。需要注意的是,提供CredentialsURI响应的后端服务需要实现STS Token的自动刷新逻辑,确保您的应用程序始终能获取到有效凭证。

  1. 为了使Credentials工具正确解析和使用STS Token,URI必须遵循以下响应协议:

    • 响应状态码:200

    • 响应体结构:

      {
        "Code": "Success",
        "AccessKeySecret": "AccessKeySecret",
        "AccessKeyId": "AccessKeyId",
        "Expiration": "2021-09-26T03:46:38Z",
        "SecurityToken": "SecurityToken"
      }
  2. 配置CredentialsURI作为访问凭证,完成客户端初始化。

    const OSS = require("ali-oss");
    const Credential = require("@alicloud/credentials");
    
    // 通过凭证的 URI 初始化Credentials Client。
    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 credential = await credentialClient.getCredential();
    
    // 初始化OSS
    const client = new OSS({
      accessKeyId: credential.accessKeyId,
      accessKeySecret: credential.accessKeySecret,
      stsToken: credential.securityToken,
      refreshSTSTokenInterval: 0, // 由Credential控制accessKeyId、accessKeySecretstsToken值的更新
      refreshSTSToken: async () => {
        const { accessKeyId, accessKeySecret, securityToken } = await credentialClient.getCredential();
    
        return {
          accessKeyId,
          accessKeySecret,
          stsToken: securityToken,
        };
      }
    });
    
    // listBuckets
    const buckets = await client.listBuckets();
    console.log(buckets);
    

后续步骤

初始化凭证提供者后,您需要使用凭证提供者来创建OSSClient实例。详情请参见初始化