

 [适用于 JavaScript 的 AWS SDK V3 API 参考指南](https://docs.aws.amazon.com/AWSJavaScriptSDK/v3/latest/)详细描述了 适用于 JavaScript 的 AWS SDK 版本 3 (V3) 的所有 API 操作。

本文属于机器翻译版本。若本译文内容与英语原文存在差异，则一律以英文原文为准。

# 设置凭证
<a name="setting-credentials"></a>

AWS 使用证书来识别谁在呼叫服务以及是否允许访问所请求的资源。

无论是在 Web 浏览器中还是在 Node.js 服务器中运行，您的 JavaScript 代码都必须先获得有效的凭据，然后才能通过 API 访问服务。可以针对每个服务设置凭证，方法是将凭证直接传递给服务对象。

有几种方法可以设置凭证，这些方法在 Node.js 和 Web 浏览器 JavaScript中有所不同。本部分中的主题介绍如何在 Node.js 或 Web 浏览器中设置凭证。在每种情况下，选项以推荐顺序显示。

## 凭证的最佳实践
<a name="credentials-best-practices"></a>

正确设置凭证可确保您的应用程序或浏览器脚本可以访问所需的服务和资源，同时最大限度地减少可能影响关键任务型应用程序或危及敏感数据的安全问题。

设置凭证时应用的一个重要原则是始终授予您的任务所需的最小权限。提供对资源的最小权限并根据需要添加更多权限更安全，而不是提供超过最小权限的权限，因此需要修复以后可能发现的安全问题。例如，除非您需要读取和写入单独的资源（例如 Amazon S3 存储桶或 DynamoDB 表中的对象），否则请将这些权限设置为只读。

有关授予最低权限的更多信息，请参阅《IAM 用户指南》**最佳实践主题中的[授予最低权限](https://docs.aws.amazon.com/IAM/latest/UserGuide/best-practices.html#grant-least-privilege)部分。

**Topics**
+ [凭证的最佳实践](#credentials-best-practices)
+ [在 Node.js 中设置凭证](setting-credentials-node.md)
+ [在 Web 浏览器中设置凭证](setting-credentials-browser.md)

# 在 Node.js 中设置凭证
<a name="setting-credentials-node"></a>

我们建议在本地开发且雇主未向其提供身份验证方法的新用户进行设置 AWS IAM Identity Center。有关更多信息，请参阅 [使用 SDK 进行身份验证 AWS](getting-your-credentials.md)。

Node.js 有几种方法可以为 SDK 提供凭证。其中一些方法更安全，而另一些方法则在开发应用程序时可以提供更大的便利。在 Node.js 中获取凭证时，请注意依赖多个源，例如环境变量和您加载的 JSON 文件。您可以更改运行代码的权限，而不会意识到已发生更改。

适用于 JavaScript 的 AWS SDK V3 在 Node.js 中提供了默认的凭证提供者链，因此您无需明确提供凭证提供商。默认[凭证提供程序链](https://docs.aws.amazon.com/sdkref/latest/guide/standardized-credentials.html#credentialProviderChain)会尝试按给定优先级解析来自各种不同源的凭证，直到从其中一个源返回凭证。您可以在此[处](https://docs.aws.amazon.com/AWSJavaScriptSDK/v3/latest/Package/-aws-sdk-credential-providers/#fromnodeproviderchain)找到适用于 JavaScript V3 的 SDK 的凭证提供商链。

## 凭证提供程序链
<a name="credchain"></a>

所有 SDKs 人都有一系列地点（或来源）供他们检查，以便获得用于向某人提出请求的有效凭证 AWS 服务。找到有效凭证后，搜索即告停止。这种系统性搜索被称为默认凭证提供程序链。

对于链中的每个步骤，都有不同的设置值的方法。直接在代码中设置值始终优先，然后设置为环境变量，然后在共享 AWS `config`文件中设置。有关更多信息，请参阅《工具参考指南[》*AWS SDKs 和《工具参考指南》*中的设置优先级](https://docs.aws.amazon.com/sdkref/latest/guide/settings-reference.html#precedenceOfSettings)。

《*AWS SDKs 和工具参考指南》*包含有关所有 AWS SDKs 人使用的 SDK 配置设置的信息 AWS CLI。要详细了解如何通过共享 AWS `config`文件配置 SDK，请参阅[共享配置和凭据文件](https://docs.aws.amazon.com/sdkref/latest/guide/file-format.html)。要详细了解如何通过设置环境变量来配置 SDK，请参阅[环境变量支持](https://docs.aws.amazon.com/sdkref/latest/guide/environment-variables.html)。

要进行身份验证 AWS，请按下表所列顺序 适用于 JavaScript 的 AWS SDK 检查凭证提供商。

[\[See the AWS documentation website for more details\]](http://docs.aws.amazon.com/zh_cn/sdk-for-javascript/v3/developer-guide/setting-credentials-node.html)

如果您遵循推荐的新用户入门方法，则可以在入门主题的 [使用 SDK 进行身份验证 AWS](getting-your-credentials.md) 中设置 AWS IAM Identity Center 身份验证。其他身份验证方法适用于不同的情况。为避免安全风险，我们建议始终使用短期凭证。有关其他身份验证方法的步骤，请参阅《[和*工具参考指南》中的身份验证AWS SDKs 和*访问权限](https://docs.aws.amazon.com/sdkref/latest/guide/access.html)。

本部分中的主题介绍如何将凭证加载到 Node.js 中。

**Topics**
+ [凭证提供程序链](#credchain)
+ [从 IAM 角色为 Amazon EC2 加载 Node.js 中的凭证](loading-node-credentials-iam.md)
+ [加载 Node.js Lambda 函数的凭证](loading-node-credentials-lambda.md)

# 从 IAM 角色为 Amazon EC2 加载 Node.js 中的凭证
<a name="loading-node-credentials-iam"></a>

如果在 Amazon EC2 实例上运行 Node.js 应用程序，则可以利用 Amazon EC2 的 IAM 角色自动为实例提供凭证。如果将实例配置为使用 IAM 角色，则 SDK 会自动为您的应用程序选择 IAM 凭证，从而无需手动提供凭证。

有关将 IAM 角色添加到 Amazon EC2 实例的更多信息，请参阅[适用于 Amazon EC2 的 IAM 角色](https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/iam-roles-for-amazon-ec2.html)。

# 加载 Node.js Lambda 函数的凭证
<a name="loading-node-credentials-lambda"></a>

创建 AWS Lambda 函数时，必须创建一个有权执行该函数的特殊 IAM 角色。此角色称为*执行角色*。当您设置 Lambda 函数时，您必须指定您创建的 IAM 角色作为相应的执行角色。

执行角色为 Lambda 函数提供运行和调用其他 Web 服务所需的凭证。因此，您不需要为在 Lambda 函数中编写的 Node.js 代码提供凭证。

有关您创建 Lambda 执行角色的更多信息，请参阅《AWS Lambda 开发人员指南》** 中的[管理权限：使用 IAM 角色（执行角色）](https://docs.aws.amazon.com/lambda/latest/dg/intro-permission-model.html#lambda-intro-execution-role)。

# 在 Web 浏览器中设置凭证
<a name="setting-credentials-browser"></a>

有几种方法可以从浏览器脚本为 SDK 提供凭证。其中一些方法更安全，而另一些方法则在开发脚本时可以提供更大的便利。

 下面是按推荐顺序提供凭证的方法：

1. 使用 Amazon Cognito 验证用户身份和提供凭证

1. 使用 Web 联合身份验证

**警告**  
我们不建议在脚本中对您的 AWS 凭证进行硬编码。硬编码凭证存在暴露您的访问密钥 ID 和秘密访问密钥的风险。

**Topics**
+ [使用 Amazon Cognito 身份对用户进行身份验证](loading-browser-credentials-cognito.md)

# 使用 Amazon Cognito 身份对用户进行身份验证
<a name="loading-browser-credentials-cognito"></a>

获取浏览器脚本的 AWS 凭证的推荐方法是使用 Amazon Cognito Identity 凭证客户端 `CognitoIdentityClient`。Amazon Cognito 支持通过第三方身份提供商对用户进行身份验证。

要使用 Amazon Cognito Identity，您必须先在 Amazon Cognito 控制台中创建一个身份池。身份池表示应用程序为用户提供的身份组。为用户提供的身份唯一地标识每个用户账户。Amazon Cognito 身份并不是凭证。可以在 AWS Security Token Service (AWS STS) 中使用 Web 联合身份验证支持为凭证交换这些身份。

Amazon Cognito 可帮助您管理跨多个身份提供商的身份抽象。然后，在 AWS STS 中为凭证交换加载的身份。

## 配置 Amazon Cognito 身份凭证对象
<a name="browser-cognito-configuration"></a>

如果您尚未创建身份池，则在配置 Amazon Cognito 客户端之前，请先创建一个以与 [Amazon Cognito 控制台](https://console.aws.amazon.com/cognito)中的浏览器脚本一起使用。为身份池创建并关联经过身份验证和未经身份验证的 IAM 角色。有关更多信息，请参阅《Amazon Cognito 开发人员指南》**中的[教程：创建身份池](https://docs.aws.amazon.com/cognito/latest/developerguide/tutorial-create-identity-pool.html)。

未经身份验证的用户的身份未经过验证，因此，该角色很适合您的应用程序的来宾用户或用户身份验证与否无关紧要的情形。经过身份验证的用户可以通过证实其身份的第三方身份提供商登录到您的应用程序。确保您的资源的权限范围适当，让未经身份验证的用户无权访问这些资源。

配置身份池后，可使用 `@aws-sdk/credential-providers` 中的 `fromCognitoIdentityPool` 方法从身份池中检索凭证。在以下创建 Amazon S3 客户端的示例中，将 *AWS\$1REGION* 替换为区域，将 *IDENTITY\$1POOL\$1ID* 替换为身份池 ID。

```
// Import required AWS SDK clients and command for Node.js
import {S3Client} from "@aws-sdk/client-s3";
import {fromCognitoIdentityPool} from "@aws-sdk/credential-providers";

const REGION = AWS_REGION;

const s3Client = new S3Client({
  region: REGION,
  credentials: fromCognitoIdentityPool({
    clientConfig: { region: REGION }, // Configure the underlying CognitoIdentityClient.
    identityPoolId: 'IDENTITY_POOL_ID',
    logins: {
            // Optional tokens, used for authenticated login.
        },
  })
});
```

可选的 `logins` 属性是身份提供商名称到这些提供商身份令牌的映射。您如何从身份提供商获得令牌的方式取决于您使用的提供商。例如，如果您使用 Amazon Cognito 用户池作为身份验证提供商，则可以使用类似于以下方法的方法。

```
// Get the Amazon Cognito ID token for the user. 'getToken()' below.
let idToken = getToken();
let COGNITO_ID = "COGNITO_ID"; // 'COGNITO_ID' has the format 'cognito-idp.REGION.amazonaws.com/COGNITO_USER_POOL_ID'
let loginData = {
  [COGNITO_ID]: idToken,
};
const s3Client = new S3Client({
    region: REGION,
    credentials: fromCognitoIdentityPool({
    clientConfig: { region: REGION }, // Configure the underlying CognitoIdentityClient.
    identityPoolId: 'IDENTITY_POOL_ID',
    logins: loginData
  })
});

// Strips the token ID from the URL after authentication.
window.getToken = function () {
  var idtoken = window.location.href;
  var idtoken1 = idtoken.split("=")[1];
  var idtoken2 = idtoken1.split("&")[0];
  var idtoken3 = idtoken2.split("&")[0];
  return idtoken3;
};
```

## 将未经身份验证的用户切换为经过身份验证的用户
<a name="browser-switching-unauthenticated-users"></a>

Amazon Cognito 同时支持经过身份验证的用户和未经身份验证的用户。即使未经身份验证的用户不通过任何身份提供商登录，这些用户也有权访问您的资源。此级别的访问可用于向尚未登录的用户显示内容。即使每个未经身份验证的用户尚未单独登录和经过身份验证，这些用户在 Amazon Cognito 中也都具有唯一的身份。

### 最初未经身份验证的用户
<a name="browser-initially-unauthenticated-user"></a>

用户通常从未经身份验证的角色开始，为此需要设置配置对象的凭证属性而不是 `logins` 属性。在这种情况下，您的默认凭证可能如下所示：

```
// Import the required 适用于 JavaScript 的 AWS SDK v3 modules.                   
import {fromCognitoIdentityPool} from "@aws-sdk/credential-providers";
// Set the default credentials.
const creds = fromCognitoIdentityPool({
  identityPoolId: 'IDENTITY_POOL_ID',
  clientConfig: { region: REGION } // Configure the underlying CognitoIdentityClient.
});
```

### 切换为经过身份验证的用户
<a name="switch-to-authenticated"></a>

当未经身份验证的用户登录身份提供商并且您拥有令牌时，您可以通过调用可更新凭证对象和添加 `logins` 令牌的自定义函数，来将用户从未经身份验证的用户切换为经过身份验证的用户。

```
// Called when an identity provider has a token for a logged in user
function userLoggedIn(providerName, token) {
  creds.params.Logins = creds.params.logins || {};
  creds.params.Logins[providerName] = token;
                    
  // Expire credentials to refresh them on the next request
  creds.expired = true;
}
```