最近开始研究 Strapi,这是一个无头 CMS。由于它仅提供后端,前端部分包括身份验证流程需要你自己构建。显然,你不会想自己构建这些,而是使用市场上的某个身份验证库。

我早已计划使用 NextAuth,所以这是一个完美的机会来实现它。因此,我们的设置是 Next + Strapi + NextAuth。

作为 NextAuth 的新手,首先需要一些基础教程和入门指南。但在深入研究 NextAuth 时,我发现这些教程并不完善:它们不是生产就绪的、已经过时或不完整……此外,NextAuth 的文档也不太清晰。虽然提到了一些功能,但并未详细说明如何使用它们,这是文档常见的问题(在我看来)。

目标

因此,我决定深入研究并通过编写代码来搞清楚一切。

  • 使用最新的 Next,包括服务器组件和服务器操作。
  • 使用 GoogleProvider 和 CredentialsProvider(邮箱 + 密码)的 NextAuth。
  • 与 Strapi 的完全集成。

在查找了大量信息后,我发现并没有一个全面解释这个主题的资源。因此,我决定将其整理成系列文章并分享出来。这就是你现在看到的内容:唯一一个完整的 NextAuth 使用指南,涵盖了凭据提供商的使用,包括邮箱确认流程、忘记密码或更改密码以及错误处理。

即使你对 Strapi 部分不感兴趣,这个系列也能帮助你学习 NextAuth。我建议你完整阅读整个系列,因为我在某些章节中解释的内容在其他章节中会用到。更好的是,尝试跟着代码一起动手,以最大化你的学习效果。

结构
在设置章节和一些理论知识之后,我们首先设置 GoogleProvider。这是对 NextAuth 的一个简单介绍。我们不需要表单和状态,直接进入 NextAuth 的功能和自定义。一旦完成了 GoogleProvider 的身份验证过程,我们将添加 CredentialsProvider 及其所有步骤,比如登录和登出、重置密码等。

我知道这超出了预期,内容超过了20部分,我对此感到抱歉。但我保证你会对如何在 Next 中使用 Strapi 和 NextAuth 构建一个完整的身份验证流程有一个扎实的理解。所以,不要被长度吓到。

我将每一章的代码上传到了 GitHub 的分支上,你可以在那里跟着一起操作。

希望你喜欢这个系列。

2/ Next + NextAuth + Strapi:项目设置

在开始之前,我们需要进行一些安装和配置。设置代码的最终版本可以在 GitHub(setup 分支)上查看。

1. Next

首先在名为 frontend 的文件夹中安装 Next。运行以下命令:

npx create-next-app@latest

在设置选项中,选择 TypeScript、src 文件夹、app router 和 Tailwind。

安装完成后,我们清理大部分模板代码,以便从一个空项目开始。

2. Strapi

快速安装 Strapi。如果你想了解更多,可以查看 Strapi 快速入门指南。在名为 backend 的文件夹中安装 Strapi:

npx create-strapi-app@latest backend --quickstart --ts

--quickstart 标志表示 Strapi 会为你设置一个 SQLite 数据库。这完全是不可见的,你在开发模式中完全不需要担心这个数据库。--ts 添加了 TypeScript 支持。

我将项目命名为 backend 并选择了快速安装(Quickstart)类型。

安装完成后,Strapi 会自动启动,打开 http://localhost:1337/admin 并要求创建一个账户。这是主要的 Strapi 管理员账户,所以不要忘记这些凭据。所有数据都是本地存储的,所以你不必担心安全性。

到此为止,我们暂时完成了 Strapi 的设置。现在我们在 frontend 文件夹中有了 Next,在 backend 文件夹中有了 Strapi。

3. 使用 nodemailer 和 Brevo 在 Strapi 中设置邮件提供商

Strapi 的默认邮件插件基于 Sendmail。这可能在开发环境中有效,但在生产环境中不太可靠(如 Strapi 文档所述)。

因此,我们将使用不同的插件:provider-email-nodemailer,并与外部提供商 Brevo(以前称为 SendinBlue)结合使用。注意,Strapi 有一个特定的 Brevo 插件,但使用 Nodemailer 设置更简单,因为我们使用的是 SMTP。

首先使用 Brevo 创建一个免费账户(无需信用卡)。它每天允许发送 300 封免费邮件,这对于开发目的来说已经足够了。创建一个 SMTP 密钥。然后将 SMTP 服务器、端口、登录名和密码放入 backend 文件夹中的 .env 文件:

# /backend/.env

SMTP_HOST=smtp-relay.brevo.com
SMTP_PORT=587
SMTP_USER=EDITME->someusername
SMTP_PASS=EDITME->somepassword
SMTP_DEFAULT_FROM=EDITME->someEmail
SMTP_DEFAULT_REPLYTO=EDITME->someEmail

邮件插件允许你从 Strapi 内部发送邮件,例如从控制器或服务内部发送。为了确保这些邮件中始终存在 fromreplyto 值,我们在配置中设置了默认值(见下文),并在此处将它们声明为 SMTP_DEFAULT_FROMSMTP_DEFAULT_REPLYTO

接下来,我们将安装 Strapi 插件 provider-email-nodemailer。在 backend(Strapi)文件夹中运行:

npm i @strapi/provider-email-nodemailer

遗憾的是,这里存在一些漏洞:

17 vulnerabilities (3 moderate, 14 high)

但截至 2024 年 5 月 3 日,该插件在6天前更新过,所以应该没问题。

接下来,我们需要激活并配置这个插件。添加以下设置:

// backend/config/plugins.js

module.exports = ({ env }) => ({
  email: {
    config: {
      provider: 'nodemailer',
      providerOptions: {
        host: env('SMTP_HOST'),
        port: env('SMTP_PORT'),
        auth: {
          user: env('SMTP_USER'),
          pass: env('SMTP_PASS'),
        },
        // ... any custom nodemailer options
      },
      settings: {
        defaultFrom: env('SMTP_DEFAULT_FROM'),
        defaultReplyTo: env('SMTP_DEFAULT_REPLYTO'),
      },
    },
  },
});

测试一切是否正常工作。启动 Strapi 并进入管理面板:http://localhost:1337/admin。导航到:settings > email plugin > configuration。找到“测试邮件发送”框,输入一个邮箱地址(你的)并点击发送。如果你正确地执行了上述步骤,这将发送一封电子邮件。

一些故障排除提示:

  • 确保你在 backend 添加了环境变量!
  • 确保你在 .envconfig/plugins.js 中拼写正确。
  • 阅读后端终端中的错误信息。

大部分信息来源于这篇文章:如何轻松在 Strapi 中通过任意提供商发送电子邮件

最后一点:Brevo 提供了一个漂亮的仪表板,包含发送统计和日志,你可以在其中查看已发送的邮件。

4. Google OAuth

当你构建一个允许用户使用 Google 帐户登录的项目时,你需要在 Google Cloud 平台上创建一个 OAuth2.0 客户端。此客户端将为你提供一个 client ID 和一个 client secret,你稍后在配置 NextAuth 时会用到它们。

这个 YouTube 视频 会引导你完成整个过程。相关部分是从 3:28 到 6:00。顺便提一下,这是一位 YouTube 频道 Sakura Dev 的视频,该频道有很多关于 NextAuth 的信息,所以你可能想将其收藏。

步骤:

  1. 前往 https://console.cloud.google.com/
  2. 为 Web 应用程序创建凭据 OAuth 客户端 ID。
  3. 填写名称(例如 test project)、来源(http://localhost:3000)和回调 URL(http://localhost:3000/api/auth/callback/google)。
  4. 获取 client IDsecret,并将它们放入 frontend 文件夹根目录下的 .env.local 文件中:
# .env.local

GOOGLE_CLIENT_ID=MYGOOGLECLIENTID
GOOGLE_CLIENT_SECRET=MYGOOGLECLIENTSECRET

注意,这些是机密信息。不要将它们推送到 git 仓库!如果你不知道回调 URL 是什么,不必担心,这只是一个设置步骤。它将你的前端 Next 与 Google 提供商链接起来。

5. 项目结构
我们现在有两个文件夹:

  • frontend 用于 Next
  • backend 用于 Strapi

我在每个文件夹中添加了

一个工作区文件。这让你可以轻松地为每个文件夹打开两个 VS Code 实例。我还为每个文件夹添加了不同的背景颜色,以便轻松区分前端和后端,并隐藏了 node_modules 文件夹。

6. 一些组件和样式
在开始之前,我们添加一些组件并设置一些基本样式。我们将保持样式尽可能简单,因为这不是一篇关于用户体验的文章。

在我们的 root layout.tsx 中,我们添加了一个 <NavBar /> 组件,目前只包含一个指向主页的链接。

export default async function NavBar() {
  return (
    <nav className='flex gap-4 items-center my-4 p-4 bg-zinc-100 rounded-sm'>
      <Link href='/' className='mr-auto'>
        home
      </Link>
    </nav>
  );
}

接下来的步骤
至此,我们结束了设置。在下一章中,我们将开始使用 NextAuth。

首发于公众号 大迁世界,欢迎关注。📝 每周一篇实用的前端文章 🛠️ 分享值得关注的开发工具 ❓ 有疑问?我来回答

本文 GitHub https://github.com/qq449245884/xiaozhi 已收录,有一线大厂面试完整考点、资料以及我的系列文章。


王大冶
68k 声望104.9k 粉丝