跳到主要内容

为你的 Next Auth 应用添加认证 (Authentication)

本指南将向你展示如何将 Logto 集成到你的 Next.js 应用中,使用 Next Auth。

提示
  • 在本指南中,我们假设你已经在你的 Next.js 项目中设置了 Next Auth。如果没有,请查看 Next Auth 文档 以开始使用。

前提条件​

集成​

配置 Next Auth 提供者​

在我们深入细节之前,这里是终端用户体验的快速概述。登录过程可以简化如下:

  1. 你的应用调用登录方法。
  2. 用户被重定向到 Logto 登录页面。对于原生应用,将打开系统浏览器。
  3. 用户登录并被重定向回你的应用(配置为重定向 URI)。
关于基于重定向的登录
  1. 此认证 (Authentication) 过程遵循 OpenID Connect (OIDC) 协议,Logto 强制执行严格的安全措施以保护用户登录。
  2. 如果你有多个应用程序,可以使用相同的身份提供商 (IdP)(日志 (Logto))。一旦用户登录到一个应用程序,当用户访问另一个应用程序时,Logto 将自动完成登录过程。

要了解有关基于重定向的登录的原理和好处的更多信息,请参阅 Logto 登录体验解释。


备注

在以下代码片段中,我们假设你的应用程序运行在 http://localhost:3000/。

配置登录重定向 URI​

让我们切换到 Logto Console 的应用详情页面。添加一个重定向 URI http://localhost:3000/api/auth/callback/logto 并点击“保存更改”。

Logto Console 中的重定向 URI

设置 Next Auth 提供商​

提示

你可以在管理控制台的应用详情页面找到并复制“应用密钥”:

App Secret

修改你的 Next Auth 的 API 路由配置,如果你使用的是 Pages Router,文件位于 pages/api/auth/[...nextauth].js,如果你使用的是 App Router,文件位于 app/api/auth/[...nextauth]/route.ts。

以下是 App Router 的示例:

import NextAuth from 'next-auth';

export const {
handlers: { GET, POST },
signIn,
signOut,
auth,
} = NextAuth({
providers: [
{
id: 'logto',
name: 'Logto',
type: 'oidc',
// 你可以从 Logto 应用详情页面的 "Issuer endpoint" 字段获取发行者 (Issuer) 值
issuer: 'https://xxxx.logto.app/oidc',
clientId: '<logto-app-id>',
clientSecret: '<logto-app-secret>',
authorization: {
params: { scope: 'openid offline_access profile email' },
},
profile(profile) {
// 你可以在这里自定义用户资料映射
return {
id: profile.sub,
name: profile.name ?? profile.username,
email: profile.email,
image: profile.picture,
};
},
},
],
});
  1. 将 issuer URL 替换为你的 Logto 应用的 "Issuer endpoint"。
  2. 将 clientId 和 clientSecret 替换为你的 Logto 应用的 ID 和密钥。
  3. 自定义 profile 函数以将用户资料映射到 Next Auth 用户对象,示例中显示了默认映射。

检查点​

现在,你可以测试你的应用,看看认证 (Authentication) 是否按预期工作。

权限 (Scopes) 和声明 (Claims)​

Logto 使用 OIDC 权限和声明约定 来定义从 ID 令牌和 OIDC 用户信息端点检索用户信息的权限和声明。“权限”和“声明”都是 OAuth 2.0 和 OpenID Connect (OIDC) 规范中的术语。

简而言之,当你请求一个权限时,你将获得用户信息中的相应声明。例如,如果你请求 `email` 权限,你将获得用户的 `email` 和 `email_verified` 数据。

默认情况下,Logto SDK 总是会请求三个权限:`openid`、`profile` 和 `offline_access`,并且无法移除这些默认权限。但你可以在配置 Logto 时添加更多权限:

const handler = NextAuth({
providers: [
{
id: 'logto',
name: 'Logto',
// ... other options
authorization: { params: { scope: 'openid offline_access profile email' } },
// ... other options
},
],
});

以下是支持的权限(Scopes)及其对应的声明(Claims)列表:

openid

声明名称类型描述需要用户信息吗?
substring用户的唯一标识符否

profile

声明名称类型描述需要用户信息吗?
namestring用户的全名否
usernamestring用户名否
picturestring终端用户的个人资料图片的 URL。此 URL 必须指向一个图像文件(例如,PNG、JPEG 或 GIF 图像文件),而不是包含图像的网页。请注意,此 URL 应特别引用适合在描述终端用户时显示的终端用户的个人资料照片,而不是终端用户拍摄的任意照片。否
created_atnumber终端用户创建的时间。时间表示为自 Unix 纪元(1970-01-01T00:00:00Z)以来的毫秒数。否
updated_atnumber终端用户信息最后更新的时间。时间表示为自 Unix 纪元(1970-01-01T00:00:00Z)以来的毫秒数。否

其他 标准声明 包括 family_name、given_name、middle_name、nickname、preferred_username、profile、website、gender、birthdate、zoneinfo 和 locale 也将包含在 profile 权限中,而无需请求用户信息端点。与上述声明的区别在于,这些声明只有在其值不为空时才会返回,而上述声明在值为空时将返回 null。

备注

与标准声明不同,created_at 和 updated_at 声明使用毫秒而不是秒。

email

声明名称类型描述需要用户信息吗?
emailstring用户的电子邮件地址否
email_verifiedboolean电子邮件地址是否已验证否

phone

声明名称类型描述需要用户信息吗?
phone_numberstring用户的电话号码否
phone_number_verifiedboolean电话号码是否已验证否

address

请参阅 OpenID Connect Core 1.0 以获取地址声明的详细信息。

custom_data

声明名称类型描述需要用户信息吗?
custom_dataobject用户的自定义数据是

identities

声明名称类型描述需要用户信息吗?
identitiesobject用户的关联身份是
sso_identitiesarray用户的关联 SSO 身份是

urn:logto:scope:organizations

声明名称类型描述需要用户信息吗?
organizationsstring[]用户所属的组织 ID否
organization_dataobject[]用户所属的组织数据是

urn:logto:scope:organization_roles

声明名称类型描述需要用户信息吗?
organization_rolesstring[]用户所属的组织角色,格式为 <organization_id>:<role_name>否

考虑到性能和数据大小,如果“需要用户信息吗?”为“是”,则表示声明不会显示在 ID 令牌中,而会在 用户信息端点 响应中返回。

延伸阅读​

终端用户流程:认证流程、账户流程和组织流程 配置连接器 保护你的 API