如何使用AWS Cognito进行用户身份验证

发布时间 2023-06-02 07:37:22作者: 晓风晓浪

当您构建复杂的应用程序时,一个看似简单的功能可能很难实现:用户身份验证。

尽管某些应用程序根据其用例不需要它,但很多应用程序都需要。您可能会花费大量时间构建身份验证模块来为您的用户提供安全体验并保护他们的数据和隐私。但您也可以将其提取到单独的服务中,例如 AWS Cognito。

根据该网站,

Amazon Cognito可帮助您在 Web 和移动应用程序中实施客户身份和访问管理 (CIAM)。

简而言之,AWS Cognito 旨在简化用户身份验证和授权的实施。借助 Cognito,您可以专注于构建应用程序的核心功能,同时将用户管理的复杂性转移给服务。

在本教程中,我们将通过创建用于用户身份验证的 AWS Cognito 用户池来深入了解 AWS Cognito 的世界。您将了解如何从 AWS Cognito 读取数据并将其显示在简单的 NextJS 应用程序中。

(更多教程:https://www.java567.com/?v=2306023

这是我们将要构建的应用程序的快速演示。我将更多地关注 AWS Cognito 而不是 NextJS,因为您可以将此服务移植到您希望的任何 UI 框架。

5分钟学习AWS Cognito 与 NextJS 应用程序集成

什么是 AWS Cognito 用户池?

AWS Cognito 用户池是一种完全托管的用户目录服务,允许您为您的应用程序创建和管理用户池。

用户池提供一组功能,使您能够无缝地处理用户注册、登录和帐户恢复。

AWS Cognito 用户池的优势

易于整合

Cognito 用户池与各种应用程序平台和框架无缝集成,包括 Web、移动和服务器端应用程序,使其适用于不同的用例。

安全用户认证

用户池支持多种身份验证方法,包括电子邮件和密码、社交登录(例如 Google、Facebook 或 Amazon)和多重身份验证。这确保了用户身份验证的强大安全性。

用户注册与管理

用户池通过提供可定制的注册页面和电子邮件验证来简化用户注册过程。它还提供用户自助服务功能,如密码重置和配置文件管理,减轻应用程序后端的负担。

可扩展性和性能

AWS 负责处理用户池的可扩展性和性能方面的问题,使您能够无缝处理数百万用户,而无需担心基础设施配置或性能优化。

如何创建 AWS Cognito 用户池

让我们深入了解创建 AWS Cognito 用户池的分步过程。

登录 AWS 管理控制台

使用您的凭证登录您的 AWS 管理控制台。

AWS Cognito 服务

在 AWS 管理控制台搜索栏中搜索“Cognito”并打开 Cognito 服务。您将看到如下所示的页面:

图片132AWS Cognito 控制台

创建用户池

单击“创建用户池”按钮。您可以看到两种提供程序类型。一个是默认选择的 Cognito 用户池,它提供常规的电子邮件和密码身份验证。另一个是联合身份提供者,它允许用户使用他们的社交身份登录,如 Facebook、谷歌等。

为简单起见,我仅选择 Cognito 用户池并选择用户名和电子邮件作为登录选项

图片133AWS Cognito - 配置登录选项

配置安全要求

配置所需的设置,例如密码策略、多重身份验证、MFA 方法和用户帐户恢复。

图片134AWS Cognito - 设置密码策略和 MFA

图片136AWS Cognito - 设置用户帐户恢复

配置注册体验

根据您的需要配置注册体验。您可以设置必需的属性和自定义属性,这些属性将在注册页面上显示给用户。这些数据将存储在 Cognito 用户池中。

配置消息传递

您需要为生产应用程序选择电子邮件提供商作为“SES”。由于这是一个演示,我选择“使用 Cognito 发送电子邮件”选项。

图片138AWS Cognito - 配置消息传递

整合您的应用

为您的用户池提供一个唯一的名称。选中“使用 Cognito 托管 UI”选项以使用 AWS 提供的 UI。

图片139AWS Cognito - 集成应用程序

选择您想要的域类型。要使用自定义域,您必须提供 DNS 记录和 AWS Certificate Manager 证书。

图片140AWS Cognito - 选择域类型

下一步是初始化应用程序客户端。此应用程序客户端代表您的应用程序并允许它与用户池交互。配置应用程序客户端设置,包括允许的 OAuth 范围和回调 URL。在我们这里的例子中,它将是 http://locahost:3000,因为我们将只在我们的本地机器上运行。

输入用户友好的“App 客户端名称”。您需要提供您网站的回调 URL。身份验证后,用户将被重定向到此 URL。

我们必须查询 Cognito 服务以获取用户详细信息。为此,我们需要一个客户机密。选择“生成客户端密码”选项。

浏览页面上的所有其他选项并根据您的需要进行配置。我希望它们是不言自明的。如果您不理解任何选项,请将它们保留为默认选择。

图片141AWS Cognito - 生成客户端密钥

审查和创建

最后,将显示一个审查页面,您可以在其中审查所有配置。单击“创建池”以创建您的用户池。

我们已经完成了一半。我们已经成功创建了用户池。

托管 UI 自定义

要自定义您的登录页面,请单击您刚刚创建的用户池,然后单击 App Integration 选项卡。

应用程序集成选项卡AWS Cognito - 应用程序集成选项卡

找到托管 UI 自定义并单击“编辑”按钮。您可以上传您的徽标和自定义 CSS,这将应用于注册和登录页面。

托管 UI 定制AWS Cognito - 托管 UI 自定义

您可以通过构建以下 URL 以及您的用户池的具体信息并将其输入浏览器来查看应用了自定义的托管 UI https://<your_domain>/login?response_type=code&client_id=<your_app_client_id>&redirect_uri=<your_callback_url>:。您可以从仪表板中提取所有数据。

点击网址。如果您没有看到加载的登录页面而是看到错误页面,请不要惊慌。您在仪表板上所做的更改可能需要几分钟才能生效。

图片-144登录页面

由于我们没有创建任何帐户,让我们尝试注册。AWS Cognito 处理发送验证电子邮件、要求用户设置 MFA 等所有麻烦。

图片-145注册页面

图片146AWS Cognito - 电子邮件验证

图片-147AWS Cognito - MFA

希望在按下最后的“登录”按钮时,您会被带到一个错误页面。你知道为什么吗?我们没有启动和运行我们的客户端。如果您注意到该 URL,您将进入http://localhost:3000.

但是,现在是我们验证我们的集成是否正确的正确时机。让我们打开用户池仪表板,看看我们新注册的用户是否显示在那里。

图片-148AWS Cognito - 用户数据库

做得好!我们的第一个用户出现在仪表板中。现在让我们使用 NextJS 从 Cognito 中提取用户信息。

如何使用 NextJS 从 AWS Cognito 中提取用户信息

要从 Cognito 中提取数据,我们将使用 Cognito 提供的 API。首先,我们需要使用令牌端点获取访问令牌,并使用该访问令牌通过用户信息端点获取用户信息

为了跟随我,你可以使用这个包含 NextJS 样板代码的repo 。

克隆repo,输入命令安装依赖yarn install,输入命令运行app yarn dev

完成后,您将在点击后登陆此页面http://localhost:3000

图片-149

如果您遵循与我们上面相同的注册/登录流程,您将被重定向到上述页面。

向 AWS Cognito 令牌端点发布请求

样品要求:

 POST https://mydomain.auth.us-east-1.amazoncognito.com/oauth2/token&Content-Type='application/x-www-form-urlencoded'&Authorization=Basic ZGpjOTh1M2ppZWRtaTI4M2V1OTI4OmFiY2RlZjAxMjM0NTY3ODkw                            
 &grant_type=authorization_code&client_id=1example23456789&code=AUTHORIZATION_CODE&redirect_uri=com.myclientapp://myclient/redirect

令牌端点需要以下参数:

  1. 域名– 转到 Cognito 用户池,在应用程序集成选项卡中,您可以找到域名。

  2. Client ID 和 Client Secret – 在同一页面的底部,找到应用程序客户端列表并单击您创建的应用程序客户端。您可以看到客户端 ID 和客户端密码。

  3. 授权码——这是我们被重定向到的 URL 中可用的代码。(参考下面的截图)

图片-150AWS Cognito - 授权码

让我们编写代码来获取授权码。

打开index.tsx文件并添加以下代码:

 import { useSearchParams } from "next/navigation";
 ...
 ...
 export default function Home() {
 const searchParams = useSearchParams();
 const code = searchParams.get("code");
 ...

在项目根文件夹中创建一个.env.local文件,并将以下凭据添加到其中:

 NEXT_PUBLIC_COGNITO_CLIENT_ID=<cognito_client_id>
 NEXT_PUBLIC_COGNITO_CLIENT_SECRET=<cognito_client_secret>
 NEXT_PUBLIC_COGNITO_DOMAIN=<cognito_domain>

现在useEffect在其中添加以下代码块:

 import axios from 'axios';
 
 ...
 
 export default function Home() {
  const searchParams = useSearchParams();
  const code = searchParams.get("code");
  const [name, setName] = useState("");
  const [email, setEmail] = useState("");
  useEffect(() => {
    if (!code) return;
    const clientID = process.env.NEXT_PUBLIC_COGINTO_CLIENT_ID || "";
    const clientSecret = process.env.NEXT_PUBLIC_COGNITO_CLIENT_SECRET || "";
    const cognitoDomain = process.env.NEXT_PUBLIC_COGNITO_DOMAIN || "";
    const credentials = `${clientID}:${clientSecret}`;
    const base64Credentials = Buffer.from(credentials).toString("base64");
    const basicAuthorization = `Basic ${base64Credentials}`;
    const headers = {
      "Content-Type": "application/x-www-form-urlencoded",
      Authorization: basicAuthorization,
    };
    const data = new URLSearchParams();
    let token = "";
    data.append("grant_type", "authorization_code");
    data.append("client_id", clientID);
    data.append("code", code);
    data.append("redirect_uri", "http://localhost:3000");
    axios
      .post(
        `${cognitoDomain}/oauth2/token`,
        data,
        { headers }
      )
      .then((res) => {
        if (res.status != 200) return;
        token = res?.data?.access_token;
        const userInfoHeaders = {
          Authorization: "Bearer " + token,
        };
        axios
          .get(
            `${cognitoDomain}/oauth2/userInfo`,
            { headers: userInfoHeaders }
          )
          .then((userInfo) => {
            if (userInfo.status != 200) return;
            setName(userInfo.data?.username);
            setEmail(userInfo.data?.email);
          });
      });
  }, [code]);
 
 ...
 ...

我们在上面的代码中做了什么?让我们探索一下。

我们需要获取访问令牌。每当用户使用该应用程序时,都需要此令牌来授权用户。

要获得该令牌,我们必须向 AWS Cognito 服务发出 HTTP POST 请求,在授权标头中附加我们的客户端 ID 和密码的 Base64 编码。此外,我们还必须传递在重定向用户时从 URL 收到的代码。

我们将使用此令牌来获取用户的信息。我们将用户信息(姓名和电子邮件)存储在应用程序的状态变量中。

我们从上面的代码中得到了用户的姓名和电子邮件。让我们在屏幕上显示它们。

 ...
 ...
 <h2 className={inter.className}>Welcome to 5minslearn!</h2>
      {name && email ? (
        <>
          <h2 className={inter.className}>{name}</h2>
          <p className={inter.className}>{email}</p>
        </>
      ) : (
        <></>
      )}
 ...
 ...

惊人的。我们的应用程序现在已经完全准备好了。

一旦您再次从 Cognito 登录,您将被重定向到您的站点,并且您将看到一个包含您的姓名和电子邮件的页面(如下面的屏幕截图所示)。

图片-151使用 Next.js 从 AWS Cognito 获取用户名和电子邮件

太棒了——我们成功地从 AWS Cognito 中提取数据并将其显示在我们的应用程序中。

结论

在本教程中,您学习了如何通过创建 Cognito 用户池来构建用户身份验证。您还了解了如何使用 NextJS 从 Amazon Cognito 中提取数据。

希望你喜欢阅读这篇文章!

(更多教程:https://www.java567.com/?v=2306023