如何使用 Auth0 在 Next.js 中实现身份验证
已发表: 2022-03-10“身份验证”是验证用户是他或她声称的身份的操作。 我们通常通过实施凭据系统来做到这一点,例如用户/密码、安全问题,甚至面部识别。
“授权”决定了用户可以(或不能)做什么。 如果我们需要在我们的 Web 应用程序中处理身份验证和授权,我们将需要一个安全平台或模块。 我们可以开发自己的平台,实施并维护它。 或者我们可以利用市场上现有的以服务形式提供的身份验证和授权平台。
在评估我们是否更好地创建自己的平台或使用第三方服务时,我们应该考虑以下几点:
- 设计和创建身份验证服务不是我们的核心技能。 有些人专门专注于安全主题,可以创建比我们更好、更安全的平台;
- 我们可以依靠现有的身份验证平台节省时间,并将其用于为我们关心的产品和服务增加价值;
- 我们不会在我们的数据库中存储敏感信息。 我们将其与我们应用程序中涉及的所有数据分开;
- 第三方服务提供的工具提高了可用性和性能,这使我们更容易管理我们应用程序的用户。
考虑到这些因素,我们可以说依赖第三方认证平台比创建自己的安全模块更容易、更便宜,甚至更安全。
在本文中,我们将了解如何使用市场上现有的产品之一:Auth0 在我们的 Next.js 应用程序中实现身份验证和授权。
什么是 Auth0?
它允许您为使用任何编程语言或技术开发的应用程序添加安全性。
“Auth0 是一种灵活的插入式解决方案,可为您的应用程序添加身份验证和授权服务。”
——丹·阿里亚斯,auth0.com
Auth0 有几个有趣的特性,例如:
- 单点登录:登录到使用 Auth0 的应用程序后,在输入另一个也使用它的应用程序时,您无需再次输入您的凭据。 您将自动登录到所有这些;
- 社交登录:使用您首选的社交网络配置文件进行身份验证;
- 多重身份验证;
- 允许使用多种标准协议,例如 OpenID Connect、JSON Web Token 或 OAuth 2.0;
- 报告和分析工具。
有一个免费计划可用于开始保护您的 Web 应用程序,每月最多可覆盖 7000 个活跃用户。 当用户数量增加时,您将开始付费。
Auth0 的另一个很酷的地方是我们有一个 Next.js SDK 可以在我们的应用程序中使用。 使用这个专为 Next.js 创建的库,我们可以轻松连接到 Auth0 API。
Next.js 的 Auth0 SDK
正如我们之前提到的,Auth0 创建(并维护)了一个专注于 Next.js 的 SDK,以及其他可用于使用各种编程语言连接到 API 的 SDK。 我们只需要下载 NPM 包,配置一些关于我们的 Auth0 帐户和连接的详细信息,我们就可以开始了。
该 SDK 为我们提供了通过客户端和服务器端方法实现身份验证和授权的工具,在后端使用 API Routes,在前端使用 React Context 和 React Hooks。
让我们看看其中一些如何在 Next.js 示例应用程序中工作。
使用 Auth0 的示例 Next.js 应用程序
让我们回到我们之前的视频平台示例,并创建一个小应用程序来展示如何使用 Auth0 Next.js SDK。 我们将设置 Auth0 的通用登录。 我们将有一些 YouTube 视频 URL。 它们将隐藏在身份验证平台下。 只有注册用户才能通过我们的网络应用程序查看视频列表。
注意:本文重点介绍 Auth0 在 Next.js 应用程序中的配置和使用。 我们不会深入讨论 CSS 样式或数据库使用等细节。 如果您想查看示例应用程序的完整代码,可以访问此 GitHub 存储库。
创建 Auth0 帐户并配置应用程序详细信息
首先,我们需要使用注册页面创建一个 Auth0 帐户。
之后,让我们转到 Auth0 Dashboard。 转到应用程序并创建一个类型为 [“常规 Web 应用程序”] 的新应用程序。
现在让我们转到应用程序的“设置”选项卡,在“应用程序 URI ”部分下,配置以下详细信息并保存更改:
- 允许的回调 URL :添加
https://localhost:3000/api/auth/callback
- 允许注销 URL :添加
https://localhost:3000/
通过这样做,我们正在配置我们希望在用户登录我们的网站后重定向的 URL(回调),以及我们在用户注销后重定向的 URL(注销)。 当我们将应用程序的最终版本部署到托管服务器时,我们应该添加生产 URL。
Auth0 Dashboard 有许多我们可以应用到我们的项目中的配置和自定义。 我们可以更改我们使用的身份验证类型、登录/注册页面、我们为用户请求的数据、启用/禁用新注册、配置用户数据库等等。
创建 Next.js 应用
要创建一个全新的 Next.js 应用程序,我们将使用 create-next-app,它会自动为您设置所有内容。 要创建项目,请运行:
npx create-next-app [name-of-the-app]
要么
yarn create next-app [name-of-the-app]
要在本地启动开发服务器并查看刚刚在浏览器中创建的站点,请转到您创建的新文件夹:
cd [name-of-the-app]
并运行:
npm run dev
要么
yarn dev
安装和配置 Auth0 Next.js SDK
让我们在我们的应用程序中安装 Auth0 Next.js SDK:
npm install @auth0/nextjs-auth0
要么
yarn add @auth0/nextjs-auth0
现在,在我们的 env.local 文件(或我们托管平台的环境变量菜单)中,让我们添加这些变量:
AUTH0_SECRET="[A 32 characters secret used to encrypt the cookies]" AUTH0_BASE_URL="https://localhost:3000" AUTH0_ISSUER_BASE_URL="https://[Your tenant domain. Can be found in the Auth0 dashboard under settings]" AUTH0_CLIENT_ AUTH0_CLIENT_SECRET="[Can be found in the Auth0 dashboard under settings]"
如果您需要更多配置选项,可以查看文档。
创建动态 API 路由
Next.js 提供了一种创建无服务器 API 的方法:API Routes。 使用此功能,我们可以创建将在每个用户对我们的路由的请求中执行的代码。 我们可以定义固定路由,例如/api/index.js
。 但是我们也可以有动态的 API 路由,我们可以在 API 路由代码中使用参数,例如/api/blog/[postId].js
。
让我们创建文件/pages/api/auth/[...auth0].js
,这将是一个动态 API 路由。 在文件内部,让我们从 Auth0 SDK 中导入handleAuth
方法,并导出结果:
import { handleAuth } from '@auth0/nextjs-auth0'; export default handleAuth();
这将创建并处理以下路由:
-
/api/auth/login
使用 Auth0 执行登录或注册。 -
/api/auth/logout
注销用户。 -
/api/auth/callback
成功登录后重定向用户。 -
/api/auth/me
获取用户配置文件信息。
这将是我们应用程序的服务器端部分。 如果我们想登录我们的应用程序或注册一个新帐户,我们应该访问https://localhost:3000/api/auth/login
。 我们应该在我们的应用程序中添加一个指向该路由的链接。 从我们的站点注销也是如此:添加指向https://localhost:3000/api/auth/logout
的链接。
添加 UserProvider 组件
要在我们的 Web 应用程序的前端处理用户身份验证状态,我们可以使用 Auth0 Next.js SDK 上提供的UserProvider
React 组件。 该组件在内部使用 React Context。
如果要访问组件上的用户身份验证状态,则应使用UserProvider
组件包装它。
<UserProvider> <Component {...props} /> </UserProvider>
如果我们想访问应用程序中的所有页面,我们应该将组件添加到pages/_app.js
文件中。 pages/_app.js
覆盖了 React App
组件。 这是 Next.js 为自定义我们的应用程序而公开的一项功能。 你可以在这里读更多关于它的内容。
import React from 'react'; import { UserProvider } from '@auth0/nextjs-auth0'; export default function App({ Component, pageProps }) { return ( <UserProvider> <Component {...pageProps} /> </UserProvider> ); }
我们有一个 React 钩子useUser
可以访问UserProvider
暴露的身份验证状态。 例如,我们可以使用它来创建一种欢迎页面。 让我们更改pages/index.js
文件的代码:
import { useUser } from "@auth0/nextjs-auth0"; export default () => { const { user, error, isLoading } = useUser(); if (isLoading) return <div>Loading...</div>; if (error) return <div>{error.message}</div>; if (user) { return ( <div> <h2>{user.name}</h2> <p>{user.email}</p> <a href="/api/auth/logout">Logout</a> </div> ); } return <a href="/api/auth/login">Login</a>; };
user
对象包含与用户身份相关的信息。 如果访问该页面的人没有登录(我们没有可用的user
对象),我们将显示一个指向登录页面的链接。 如果用户已经通过身份验证,我们将在页面上显示user.name
和user.email
属性,以及一个注销链接。
让我们创建一个 videos.js 文件,其中包含三个 YouTube 视频 URL 的列表,这些 URL 仅对注册用户可见。 为了只允许登录用户查看此页面,我们将使用 SDK 中的withPageAuthRequired
方法。
import { withPageAuthRequired } from "@auth0/nextjs-auth0"; export default () => { return ( <div> <a href="https://www.youtube.com/watch?v=5qap5aO4i9A">LoFi Music</a> <a href="https://www.youtube.com/watch?v=fEvM-OUbaKs">Jazz Music</a> <a href="https://www.youtube.com/watch?v=XULUBg_ZcAU">Piano Music</a> </div> ); }; export const getServerSideProps = withPageAuthRequired();
考虑到我们的 Web 应用程序允许任何人使用 Auth0 平台注册帐户。 用户还可以重新使用现有的 Auth0 帐户,因为我们正在实施通用登录。
我们可以创建自己的注册页面来请求有关用户的更多详细信息或添加付款信息以每月向他们收取我们的服务费用。 我们还可以使用 SDK 中公开的方法以自动方式处理授权。
结论
在本文中,我们了解了如何使用身份验证和授权平台 Auth0 来保护 Next.js 应用程序的安全。 与创建我们自己的安全平台相比,我们评估了使用第三方服务对我们的 Web 应用程序进行身份验证的好处。 我们创建了一个示例 Next.js 应用程序,并使用 Auth0 免费计划和 Auth0 Next.js SDK 保护它。
如果您想将 Auth0 示例应用程序部署到 Vercel,可以在此处进行。
进一步阅读和资源
- Auth0 Next.js SDK GitHub 存储库,Auth0,GitHub
- “使用 Auth0 进行 Next.js 身份验证的终极指南”,Sandrino Di Mattia,Auth0 博客
在我们的示例应用程序中,我们使用了服务器端渲染、API 路由和无服务器方法。 如果您将 Next.js 用于静态站点,或者使用自定义服务器来托管您的应用程序,那么本文将详细介绍如何实现身份验证。 - “新的通用登录体验”,Auth0 通用登录,Auth0 文档
- “集中式通用登录与嵌入式登录”,Auth0 通用登录,Auth0 文档