这个 @auth0/auth0-server-js 库允许在 JavaScript 运行时执行网络应用程序中的用户认证.
在您的应用程序中使用这个 SDK 可能不是微不足道的,因为它被设计为构建框架特定认证 SDK 的构件.
文档
开始
- 1. 安装SDK
- 2. 创建 Auth0 SDK 客户端
- 3. 仓库配置
- 4. 在应用程序中添加登录(互动)
- 5. 在应用程序中添加登录
- 6. 数据库连接(签名和更改密码)
- 7. 匿名会议
- 8. 钥匙
1. 安装SDK
npm i @auth0/auth0-server-js
这个库需要Node.js 20 LTS和较新的LTS版本.
2. 创建 Auth0 SDK 客户端
创建实例 ServerClient。此实例将被导入并用于我们需要访问认证方法的任何地方.
import { ServerClient } from '@auth0/auth0-server-js';
const auth0 = new ServerClient<StoreOptions>({
domain: '<AUTH0_DOMAIN>',
clientId: '<AUTH0_CLIENT_ID>',
clientSecret: '<AUTH0_CLIENT_SECRET>',
authorizationParams: {
redirect_uri: '<AUTH0_REDIRECT_URI>',
},
});
这个 AUTH0_DOMAIN, (中文(简体) ), AUTH0_CLIENT_ID,以及 AUTH0_CLIENT_SECRET 可从 Auth0 剪贴板 一旦你创建了一个应用程序. 此申请必须是 Regular Web Application。 。 。 .
这个 AUTH0_REDIRECT_URI 需要告诉 Auth0 在成功认证后返回的 URL, 例如 . http://localhost:3000/auth/callback您的应用程序需要处理此端点并呼叫 SDK completeInteractiveLogin(url: string) 以完成认证进程。 详情见下文.
3. 仓库配置
这个 auth0-server-js 但是,SDK有一个内置的商店,用于交易和状态数据 它必须提供 CookieHandler 执行 这符合你的用法.
目标 auth0-server-js 即提供一个灵活的 API , 允许您使用您喜欢的任何存储机制, 但大多是设计与 cookie 和会话存储配合.
SDK 方法接受可选 storeOptions 对象,可以用来传递存储方法的额外选项,如请求/响应对象,允许控制存储层中的 cookie.
就Web应用程序而言,这可归结为无国籍人或国家完整会话存储系统.
无国籍存储
在无国籍存储解决方案中,整个会话数据被存储在饼干中. 这是最简单的存储形式,但它有一些局限性,例如饼干的最大尺寸.
实施可能因选择的框架而异,这里是一个使用Fastify的例子:
import { FastifyReply, FastifyRequest } from 'fastify';
import { CookieSerializeOptions } from '@fastify/cookie';
import {
AbstractStateStore,
AbstractTransactionStore,
ServerClient,
StateData,
TransactionData
} from '@auth0/auth0-server-js';
export interface StoreOptions {
request: FastifyRequest;
reply: FastifyReply;
}
export class FastifyCookieHandler implements CookieHandler<StoreOptions> {
setCookie(
name: string,
value: string,
options?: CookieSerializeOptions,
storeOptions?: StoreOptions
): void {
// Handle storeOptions being undefined if needed.
storeOptions!.reply.setCookie(name, value, options || {});
}
getCookie(name: string, storeOptions?: StoreOptions): string | undefined {
// Handle storeOptions being undefined if needed.
return storeOptions!.request.cookies?.[name];
}
getCookies(storeOptions?: StoreOptions): Record<string, string> {
// Handle storeOptions being undefined if needed.
return storeOptions!.request.cookies as Record<string, string>;
}
deleteCookie(name: string, storeOptions?: StoreOptions): void {
// Handle storeOptions being undefined if needed.
storeOptions!.reply.clearCookie(name);
}
}
const auth0 = new ServerClient<StoreOptions>({
transactionStore: new CookieTransactionStore({ secret: options.secret }, new FastifyCookieHandler()),
stateStore: new StatelessStateStore({ secret: options.secret }, new FastifyCookieHandler()),
});
状态存储
在状态存储中,会话数据被存储在服务器侧存储机制中,例如数据库. 这使得会话数据的规模有了更大的灵活性,但需要额外的基础设施来管理存储. 会话由存储在饼干中的独特标识符来识别,存储会读取,以从服务器侧存储取会话数据.
实施可能因选择的框架而异,这里是一个使用Fastify的例子:
import type { FastifyReply, FastifyRequest } from "fastify";
import { CookieSerializeOptions } from '@fastify/cookie';
import {
AbstractStateStore,
LogoutTokenClaims,
ServerClient,
StateData,
} from '@auth0/auth0-server-js';
export interface StoreOptions {
request: FastifyRequest;
reply: FastifyReply;
}
export class FastifyCookieHandler implements CookieHandler<StoreOptions> {
setCookie(
name: string,
value: string,
options?: CookieSerializeOptions,
storeOptions?: StoreOptions,
): void {
// Handle storeOptions being undefined if needed.
storeOptions!.reply.setCookie(name, value, options || {});
}
getCookie(name: string, storeOptions?: StoreOptions): string | undefined {
// Handle storeOptions being undefined if needed.
return storeOptions!.request.cookies?.[name];
}
getCookies(storeOptions?: StoreOptions): Record<string, string> {
// Handle storeOptions being undefined if needed.
return storeOptions!.request.cookies as Record<string, string>;
}
deleteCookie(name: string, storeOptions?: StoreOptions): void {
// Handle storeOptions being undefined if needed.
storeOptions!.reply.clearCookie(name);
}
}
const auth0 = new ServerClient<StoreOptions>({
transactionStore: new CookieTransactionStore({ secret: options.secret }, new FastifyCookieHandler()),
stateStore: new StatefulStateStore({ secret: options.secret }, new FastifyCookieHandler()),
});
请注意: storeOptions 在 SDK 的方法中是可选的,但在想要与框架交互设置 cookie 时需要. 这是如何通过 storeOptions 改为 startInteractiveLogin() 在快捷应用程序中:
fastify.get('/auth/login', async (request, reply) => {
const storeOptions = { request, reply };
const authorizationUrl = await auth0Client.startInteractiveLogin({}, storeOptions);
reply.redirect(authorizationUrl.href);
});
因为Web应用程序中的存储系统大多以饼干为基础 storeOptions 对象用来通过 request 财务报告和审定财务报表 reply (以快活为例) 对存储方法提出异议,允许控制存储层中的饼干. 预计它会传递给与SDK的每一次互动.
4. 在应用程序中添加登录(互动)
在使用基于重定向的登录之前,确保 authorizationParams.redirect_uri 初始化 SDK 时配置 :
const auth0 = new ServerClient<StoreOptions>({
// ...
authorizationParams: {
redirect_uri: '<AUTH0_REDIRECT_URI>',
},
// ...
});
这个 redirect_uri 必须是绝对的 URL.
如果您需要计算每个请求的绝对重定向URI(例如,多域部署),则通过 authorizationParams.redirect_uri 改为 startInteractiveLogin 以覆盖已配置的默认值.
[大
您需要注册AUTH0_REDIRECT_URI在您的 Auth0 应用程序中 允许召回 URL 通过 Auth0 剪贴板数字 :
要添加登录到任何应用程序, 请打电话 startInteractiveLogin(),然后将用户重定向到返回的 URL.
执行情况将因所使用的框架而异,但这里举出一个例子,说明在Fastify中,这种情况将是什么样子:
fastify.get('/auth/login', async (request, reply) => {
const authorizationUrl = await auth0Client.startInteractiveLogin({
// The redirect_uri can also be configured here.
authorizationParams: {
redirect_uri: '<AUTH0_REDIRECT_URI>',
},
}, { request, reply });
reply.redirect(authorizationUrl.href);
});
一旦用户得到顺利的认证, Auth0 将会将用户重定向到提供的 authorizationParams.redirect_uri 在申请中需要处理.
执行情况将因所使用的框架而异,但需要的是:
- 注册一个处理所配置的结束点
authorizationParams.redirect_uri。 。 。 . - 给SDK打电话
completeInteractiveLogin(url),将其传递完整 URL,包括查询参数.
以下是在Fastify中这个样子的例子 authorizationParams.redirect_uri 配置为 http://localhost:3000/auth/callback数字 :
fastify.get('/auth/callback', async (request, reply) => {
await auth0Client.completeInteractiveLogin(new URL(request.url, options.appBaseUrl), { request, reply });
reply.redirect('/');
});
5. 在应用程序中添加登录
为了从您的应用程序以及Auth0上登录用户,您可以调用 SDK 的 logout() 方法,并重定向用户返回返回的 URL.
fastify.get('/auth/logout', async (request, reply) => {
const logoutUrl = await auth0Client.logout({ returnTo: '<RETURN_TO>' }, { request, reply });
reply.redirect(logoutUrl.href);
});
[大
您需要注册RETURN_TO在您的 Auth0 应用程序中 允许登录 URL 通过 Auth0 剪贴板数字 :
6. 数据库连接(签名和更改密码)
这个 ServerClient 暴露一个 database 子客户端 signUp 财务报告和审定财务报表 changePassword 对Auth0的自助登记和密码重置请求 数据库连接这些是: 纯通过 操作到基础认证 API——它们确实 没有 读取或写入会话/状态存储,所以操作本身不需要存储选项.
import { ServerClient, SignUpError, ChangePasswordError } from '@auth0/auth0-server-js';
// Register a new user
try {
const user = await auth0Client.database.signUp({
email: '[email protected]',
password: 'a-Str0ng-Password!',
connection: 'Username-Password-Authentication',
// Optional profile fields: username, givenName, familyName, name, nickname, picture, userMetadata
});
console.log(user.id); // normalized identifier; may be undefined if the server omits one
} catch (error) {
if (error instanceof SignUpError) {
console.error(error.code, error.message, error.cause);
}
}
// Request a password-change email
try {
const message = await auth0Client.database.changePassword({
email: '[email protected]', // or `username: 'jane'` for username-only connections
connection: 'Username-Password-Authentication',
// Optional: organization
});
console.log(message); // plain-text confirmation from the server
} catch (error) {
if (error instanceof ChangePasswordError) {
console.error(error.code, error.message);
}
}
[大 这叫大众
/dbconnections/*端点,仅发送clientId(从来不是客户的秘密).changePassword决定: 纯文本 确认字符串。 既不读又写会话/状态存储, 因此您可以在认证的请求上下文之外调用它们 。 域选择独立于会话状态:在静态模式下,构建器-配置domain在解析器(多租户)模式中domain解析器仍为每个调用——通过storeOptions这样它就可以选择预定租户.
关于全部选项和错误处理,见 auth0-auth-js 数据库连接示例 (基础数据库客户端相同)和可运行 examples/database-conns 样本.
7. 匿名会议
这个 ServerClient 暴露一个 anonymous 给访客身份的子客户端, 以及您 API 的访问符, 在登录前。 配置一个 anonymousStore 打开它:
import { StatelessAnonymousStore, ServerClient } from '@auth0/auth0-server-js';
const auth0 = new ServerClient<StoreOptions>({
// ...
anonymousStore: new StatelessAnonymousStore({ secret: options.secret }, new FastifyCookieHandler()),
});
// Give the visitor an anonymous identity and a token for your API.
const tokenSet = await auth0.anonymous.createSession(
{ audience: '<AUTH0_AUDIENCE>', metadata: { campaign: 'summer-sale' } },
{ request, reply }
);
// Later requests reuse the cached token, or mint a new one when it expired.
const { accessToken } = await auth0.anonymous.getAccessToken({ audience: '<AUTH0_AUDIENCE>' }, { request, reply });
匿名会话保存在自己的店里 所以 getSession() 财务报告和审定财务报表 getUser() 继续返回 undefined 直到访客真正登录.
打电话 createSession() 只有一次 auth0.anonymous.getSession() 显示访问者尚未开庭. getAccessToken() 服务缓存的令牌,仅在没有为请求的受众和范围提供缓存令牌时,或缓存已过期时,才能调用 Auth0 .
登入和登出都结束了你的匿名会话 每个登录方法在用户会话被写入后都会丢弃,以及 auth0.logout() 也洗干净了 读取 auth0.anonymous.getSession() 在此之前 您需要匿名时完成登录 sub 将数据合并到用户账户中,或设置 clearAnonymousSessionOnLogin: false 保持会话,自己清理.
[注] 匿名会话在早期访问中,必须允许租户使用.
[注]
startInteractiveLogin()在登录时,通过会话传输票自动将活动匿名会话链接到用户。 对于不经过的登录方法/authorize(单位:千美元)passkey.complete(), (中文(简体) ),passkey.getToken(), (中文(简体) ),completePasswordless(), (中文(简体) ),loginBackchannel(),类似地,链接是没有的——在您自己的应用程序中与匿名者合并sub。 。 。 .
完整 API、 存储选项、 清除行为以及将匿名会话连接到登录时创建的用户的详细信息, 请参见 EXAMPLES.md中的匿名会话部分。 。 。 .
8. 钥匙
这个 ServerClient 暴露一个 passkey 子客户端可以注册并登录有密码的用户(WebAuthn). 一个密码流需要两个请求:一个启动它,另一个用浏览器的证书完成. 在两者之间,SDK保持流动,包括Auth0 authSession,在交易仓库中.
// Start a signup, or a login with `auth0.passkey.startLogin()`, and return the result to the browser.
const { authnParamsPublicKey, verificationRequired } = await auth0.passkey.startSignup(
{ email: '[email protected]' },
{ request, reply }
);
// The browser passes `authnParamsPublicKey` to `navigator.credentials.create()` (`navigator.credentials.get()`
// for a login) and sends the serialized credential back, together with the one-time codes Auth0 sent to the
// identifiers in `verificationRequired`, if any. Exchange the credential for tokens and create the session:
await auth0.passkey.complete({ credential, verification }, { request, reply });
下级 passkey.register(), (中文(简体) ), passkey.challenge() 财务报告和审定财务报表 passkey.getToken() 保持不流动状态并离开 authSession 您的应用程序。 只有在需要自己保持流动时才使用.
关于仪表板设置、标识符验证、错误处理以及两套方法的不同之处,请参见 EXAMPLES.md中的密码部分。 。 。 .
反馈
捐款
我们赞赏反馈和对这次再投资的贡献! 在开始前,请阅读以下内容:
提出问题
请提供反馈或报告错误 提出我们的问题追踪器。 。 。 .
脆弱性报告
请不要在公共 GitHub 问题跟踪器上报告安全漏洞 。 这个 负责任的披露程序 详细说明披露安全问题的程序.
什么是奥特?
Auth0是一个易于执行,可适应的认证和授权平台. 学习更多退房 为什么是Auth0?
这个项目根据麻省理工学院的许可证获得许可。 见 自由主义 需要更多信息的文件.