@fastify/oauth2

中文文档
8.3.2发布于 2026/10/19MITTypeScriptCommonJS构建来源已验证近 30 天下载 42.5万

使用 oaut2 协议进行登录

中文使用文档
文档目录18 节
  1. 安装
  2. 使用量
  3. 用法为 @fastify/cookie
  4. 预设配置
  5. 自定义配置
  6. 使用自动发现终点
  7. Schema 配置
  8. 设置自定义状态
  9. 设置自定义调用参数
  10. 设置自定义符号请求正文参数
  11. 实例
  12. 参考文献
  13. 公用事业
  14. 使用类型脚本
  15. 提供方
  16. 抖动
  17. 链接
  18. 许可证

@ fastify/oaut2 (法语)

CI NPM version neostandard javascript style

环绕 simple-oauth2 图书馆.

本模块的 v4. x 支持快取 v3. x 本模块的 v3. x 支持 Fastify v2.x

安装

npm i @fastify/oauth2

使用量

在使用快取-oauth2模块时需要创建两个独立的端点,一个用于OAuth2服务提供商的回调(如Facebook或Discord),另一个用于初始化OAuth2登录流量.

const fastify = require('fastify')({ logger: { level: 'trace' } })
const oauthPlugin = require('@fastify/oauth2')

fastify.register(oauthPlugin, {
  name: 'facebookOAuth2',
  credentials: {
    client: {
      id: '<CLIENT_ID>',
      secret: '<CLIENT_SECRET>'
    },
    auth: oauthPlugin.FACEBOOK_CONFIGURATION
  },
  // register a fastify url to start the redirect flow to the service provider's OAuth2 login
  startRedirectPath: '/login/facebook',
  // service provider redirects here after user login
  callbackUri: 'http://localhost:3000/login/facebook/callback'
  // You can also define callbackUri as a function that takes a FastifyRequest and returns a string
  // callbackUri: req => `${req.protocol}://${req.hostname}/login/facebook/callback`,
})

// This is the new endpoint that initializes the OAuth2 login flow
// This endpoint is only required if startRedirectPath has not been provided
fastify.get('/login/facebook', {}, (req, reply) => {
  fastify.facebookOAuth2.generateAuthorizationUri(
    req,
    reply,
    (err, authorizationEndpoint) => {
     if (err) console.error(err)
     reply.redirect(authorizationEndpoint)
    }
  );
});

// The service provider redirect the user here after successful login
fastify.get('/login/facebook/callback', async function (request, reply) {
  const { token } = await this.facebookOAuth2.getAccessTokenFromAuthorizationCodeFlow(request, reply)

  console.log(token.access_token)

  // if later need to refresh the token this can be used
  // const { token: newToken } = await this.getNewAccessTokenUsingRefreshToken(token)

  reply.send({ access_token: token.access_token })
})

简言之,必须首先航行到 /login/facebook 在网页浏览器中手动结束点 。 这将重定向到 OAuth2 服务提供商的登录屏幕 。 从那里,服务商会自动重定向回 /login/facebook/callback 用于获取和使用访问符的终点。 这个 CLIENT_ID 财务报告和审定财务报表 CLIENT_SECRET 需要用服务提供商提供的替代.

提供了完整的示例 固定- 分解- oaut2 实例

用法为 @fastify/cookie

从v7.2.0起, @fastify/oauth2 需要使用 cookie 来安全地执行 OAuth2 交换。 因此,如果你需要的话 @fastify/cookie 你自己来, 您需要注册 在此之前 @fastify/oauth2。 。 。 .

const fastify = require('fastify')({ logger: { level: 'trace' } })
const oauthPlugin = require('@fastify/oauth2')

fastify.register(require('@fastify/cookie'), cookieOptions)
fastify.register(oauthPlugin, oauthOptions)

饼干是默认的 httpOnly, (中文(简体) ), sameSite: Lax, (中文(简体) ), path: '/'如果这不适合您的使用大小写,则可以通过在配置对象中提供选项来覆盖默认的 cookie 设置,例如

fastify.register(oauthPlugin, {
  ...,
  cookie: {
    sameSite: 'none'
  }
})

由旧版本创建但没有明确内容的饼干 path 在浏览器会话结束之前,可能仍停留在更窄的浏览器衍生路径下.

以默认饼干名称注册的多家OAuth提供商共享相同的状态和验证器饼干. 如果用户可以并行运行不止一个提供者的登录流量, 设置区分 redirectStateCookieName 财务报告和审定财务报表 verifierCookieName 每个提供者的值.

这些 cookie 的默认值是 oauth2-code-verifier 页:1 verifierCookieName 财务报告和审定财务报表 oauth2-redirect-state 页:1 redirectStateCookieName。 。 。 .

fastify.register(oauthPlugin, {
  ...,
  redirectStateCookieName: 'custom-redirect-state',
  verifierCookieName: 'custom-code-verifier'
})

已签名的饼干

cookie: { signed: true } 支持: 状态和验证 cookie 未签名 在比较状态和将核查者送到符号终点之前。 A 类 其签名无法验证的饼干被丢弃, 而不是作为实际使用 .

签名只有在请求通过 options.cookie。如果 注册 @fastify/cookie {\fn黑体\fs20\shad2\2ah82\3ah20\4ah33\fscx95\3ch592001\be1}你对你的爱 parseOptions: { signed: true },该设置 已经 没有 沉默地延伸至这两个饼干,因为插件必须知道是否 {\fn黑体\fs22\bord1\shad0\3ahbe\4ah00\fscx67\fscy66\2chffffff\3ch808080}去签它所写的.

请注意,签名不是保护这些饼干的手段. 无法阻止攻击者 从植入状态,因为一个有效的签名状态可以简单地从自己的状态中获取 登录端点。 如果符合常规,就使用它,而不是作为安全控制.

hostPrefixedCookies

hostPrefixedCookies: true 将两个默认的饼干名称切换到它们的 __Host- 前缀表格, __Host-oauth2-redirect-state 财务报告和审定财务报表 __Host-oauth2-code-verifier数字 :

fastify.register(oauthPlugin, {
  ...,
  hostPrefixedCookies: true
})

默认为 false,因为前缀名称需要为应用程序服务 超过HTTPS并默认允许它们会中断非部署. 你个 应该打开它. 它只选择默认值——一个明确的 redirectStateCookieName 或者说 verifierCookieName 总是赢.

当你应该打开它

随时打开 在您可注册的域下的任何主机都位于您的完整之外 控制。饼干是按主机而不是原产地设定的: blog.example.com 与 Domain=example.com 发送到 app.example.com因此,一个XSS上 一个营销子域,一个子域收购,一个正在移动的CNAME,一个合伙人运营 子域, 或一个被遗忘的中框, 足以让人写 oauth2-redirect-state 财务报告和审定财务报表 oauth2-code-verifier 您的应用程序主机.

这很重要,因为默认状态检查比较 state 查询参数为 州饼干。 一个人谁能写那两个饼干 可以种植一个 state 常设专家委员会 他们自己的核查员,然后让受害人的浏览器完成一个带有 授权代码 攻击者 身份——将受害人记录在 攻击者的账户,在那里他们后来所做的一切记录。 这是登录CSRF; 它不会暴露受害人自己的账户或信物.

cookie: { secure: true } 并不会阻止它。 服务器只接收 cookie 名称和 值,无法分辨在存储饼干时存在哪些属性,所以 写在非安全上下文的饼干 和你设定的饼干是分不开的.

A 类 __Host- 饼干只能由安全的源头编写,只由主机编写,所以没有 兄妹子域 或响应 HTTP 请求的政党可以创建您的主机 一个 如果您运行一个完全没有子域的单一主机名, 则旗是防御深度 而不是解决一个可以解决的问题,但促成这种问题没有代价.

这需要什么

浏览器 必须在 HTTPS 上找到您的申请。 重要的是 URL 在其中 地址栏,而不是节点本身服务的内容: Secure 由服务器发射,但 由浏览器执行, 因此 在反向代理中终止 TLS 并运行快取 plain HTTP 完全一样。无需 https 选项 实例,您不需要 trustProxy。 。 。 .

浏览器也处理 http://localhost 作为安全的环境, 所以地方发展工作 不变.

旗帜只有在浏览器真正到达应用程序时无法使用 在非浏览主机名上的 HTTP 。 这里的饼干完全无法存储, 每次登录 失败 Invalid state; 保留旗帜,或明确设置未前缀名称.

一般前缀处理

当饼干名称开始 __Host- 或者说 __Secure- - 无论是从这个旗帜还是从 你给自己定了一个名字.. @fastify/oauth2 生成前缀需要的属性 从名字,压倒任何 options.cookie 说: __Host- 部队 secure: true 财务报告和审定财务报表 path: '/' 并删除 domain, (中文(简体) ), __Secure- 部队 secure: true。前缀是 匹配不敏感大小写, 因为浏览器匹配它们 。 浏览器静悄悄地放下一个 属性与它的前缀相矛盾,所以推导它们就是使流更能运转的 而不是失败 Invalid state。 。 。 .

预设配置

您可以选择一些默认设置来指定 auth 选项.

  • APPLE_CONFIGURATION
  • FACEBOOK_CONFIGURATION
  • GITHUB_CONFIGURATION
  • GITLAB_CONFIGURATION
  • LINKEDIN_CONFIGURATION
  • GOOGLE_CONFIGURATION
  • MICROSOFT_CONFIGURATION
  • VKONTAKTE_CONFIGURATION
  • SPOTIFY_CONFIGURATION
  • DISCORD_CONFIGURATION
  • TWITCH_CONFIGURATION
  • VATSIM_CONFIGURATION
  • VATSIM_DEV_CONFIGURATION
  • EPIC_GAMES_CONFIGURATION
  • YANDEX_CONFIGURATION
  • X_CONFIGURATION

自定义配置

当然,如果一个预设不在我们的模块中,您可以自己设定ODATH的终点:

fastify.register(oauthPlugin, {
  name: 'customOauth2',
  credentials: {
    client: {
      id: '<CLIENT_ID>',
      secret: '<CLIENT_SECRET>'
    },
    auth: {
      authorizeHost: 'https://my-site.com',
      authorizePath: '/authorize',
      tokenHost: 'https://token.my-site.com',
      tokenPath: '/api/token'
    }
  },
  startRedirectPath: '/login',
  callbackUri: 'http://localhost:3000/login/callback',
  callbackUriParams: {
    exampleParam: 'example param value'
  }
})

使用自动发现终点

当您的提供者支持 OpenID 连接发现时, 您想要自动配置授权、 令牌和撤销端点, 然后你可以使用发现选项. discovery 是一个简单的对象,需要 issuer 属性.

发行者预计为字符串 URL 或元数据 URL. 支持有或无有后端斜线的备选案文.

你可以看见更多 示例。 。 。 .

fastify.register(oauthPlugin, {
  name: 'customOAuth2',
  scope: ['profile', 'email'],
  credentials: {
    client: {
      id: '<CLIENT_ID>',
      secret: '<CLIENT_SECRET>',
    },
    // Note how "auth" is not needed anymore when discovery is used.
  },
  startRedirectPath: '/login',
  callbackUri: 'http://localhost:3000/callback',
  discovery: { issuer: 'https://identity.mycustomdomain.com' }
  // pkce: 'S256', you can still do this explicitly, but since discovery is used,
  // it's BEST to let plugin do it itself
  // based on what Authorization Server Metadata response
});

重要发现说明:

  • 你不应该设置 credentials.auth 当发现力学被使用时.
  • 当您的提供者支持时, 插件也会在授权代码授权中选择适当的 PKCE 方法
  • 如果你仍然想要自己选择方法,并确切地知道自己在做什么;你仍然可以明确地这样做.

Schema 配置

您可以指定您自己的计划 startRedirectPath 结束点。 它允许您在使用 @fastify/swagger 一起来. 说明: schema 选项将覆盖 tags 选项而不合并它们.

fastify.register(oauthPlugin, {
  name: 'facebookOAuth2',
  credentials: {
    client: {
      id: '<CLIENT_ID>',
      secret: '<CLIENT_SECRET>'
    },
    auth: oauthPlugin.FACEBOOK_CONFIGURATION
  },
  // register a fastify url to start the redirect flow
  startRedirectPath: '/login/facebook',
  // facebook redirect here after the user login
  callbackUri: 'http://localhost:3000/login/facebook/callback',
  // add tags for the schema
  tags: ['facebook', 'oauth2'],
  // add schema
  schema: {
    tags: ['facebook', 'oauth2'] // this will take the precedence
  }
})

设置自定义状态

默认 @fastify/oauth2 生成随机 state把它储存在饼干里,然后在 callback 在 state 查询参数等于饼干值。 这个 是一个双向提交 cookie: 它证明了两个值匹配, 而不是同一浏览器启动 流动。 阻止另一个派对 写这些饼干的第一是 hostPrefixedCookies,你应当启用,除非你被钉住 到普通的 HTTP; 一旦调用, 状态和核查 cookie 也会被清除 已处理, 因此无法重放状态 .

为了更强有力的保证, 将状态绑定在启动流量的浏览器的会话中 在召回时消耗它. generateStateFunction 接受一个函数生成 state aWATH 流的参数。 此函数收到快取实例 request 作为参数的对象。 这个 state 参数也将被设置为 httpOnly, (中文(简体) ), sameSite: Lax 饼干. 当设置时,它需要提供功能 checkStateFunction 为了验证生成的状态.

  fastify.register(oauthPlugin, {
    name: 'facebookOAuth2',
    credentials: {
      client: {
        id: '<CLIENT_ID>',
        secret: '<CLIENT_SECRET>'
      },
      auth: oauthPlugin.FACEBOOK_CONFIGURATION
    },
    // register a fastify url to start the redirect flow
    startRedirectPath: '/login/facebook',
    // facebook redirect here after the user login
    callbackUri: 'http://localhost:3000/login/facebook/callback',
    // custom function to generate the state
    generateStateFunction: (request) => {
      const state = request.query.customCode
      request.session.state = state
      return state
    },
    // custom function to check the state is valid
    checkStateFunction: (request, callback) => {
      if (request.query.state === request.session.state) {
        callback()
        return
      }
      callback(new Error('Invalid state'))
    }
  })

这里支持Async函数,并可以通过 this。 。 。 .

  fastify.register(oauthPlugin, {
    name: 'facebookOAuth2',
    credentials: {
      client: {
        id: '<CLIENT_ID>',
        secret: '<CLIENT_SECRET>'
      },
      auth: oauthPlugin.FACEBOOK_CONFIGURATION
    },
    // register a fastify url to start the redirect flow
    startRedirectPath: '/login/facebook',
    // facebook redirect here after the user login
    callbackUri: 'http://localhost:3000/login/facebook/callback',
    // custom function to generate the state and store it into the redis
    generateStateFunction: async function (request) {
      const state = request.query.customCode
      await this.redis.set(stateKey, state)
      return state
    },
    // custom function to check the state is valid
    checkStateFunction: async function (request, callback) {
      if (request.query.state !== request.session.state) {
        throw new Error('Invalid state')
      }
      return true
    }
  })

设置自定义调用参数

这个 callbackUriParams 接受一个对象,该对象将被翻译为查询参数,用于调回的 OWATH 流量。 默认值为QQ.

fastify.register(oauthPlugin, {
  name: 'googleOAuth2',
  scope: ['profile', 'email'],
  credentials: {
    client: {
      id: '<CLIENT_ID>',
      secret: '<CLIENT_SECRET>',
    },
    auth: oauthPlugin.GOOGLE_CONFIGURATION,
  },
  startRedirectPath: '/login/google',
  callbackUri: 'http://localhost:3000/login/google/callback',
  callbackUriParams: {
    // custom query param that will be passed to callbackUri
    access_type: 'offline', // will tell Google to send a refreshToken too
  },
  pkce: 'S256'
  // check if your provider supports PKCE,
  // in case they do,
  // use of this parameter is highly encouraged
  // in order to prevent authorization code interception attacks
});

设置自定义符号请求正文参数

这个 tokenRequestParams 参数接受将翻译为 POST 正文中的额外参数的对象 在通过服务标志端点请求访问符时.

实例

见 example/ 更多示例的文件夹.

参考文献

此快速化插件将自定义实例与 simple-oauth2 实例 命名空间 由财产指定 name 有和没有 oauth2 前缀.

例如,用于 name: 'customOauth2',则 simple-oauth2 实例将像这样可以访问 :

fastify.oauth2CustomOauth2.oauth2 财务报告和审定财务报表 fastify.customOauth2.oauth2

这样,我们可以注册多个 OAuth 供应商和每个 OAuth 供应商 simple-oauth2 将活在自己 命名空间。 。 。 .

举个例子.

  • fastify.oauth2Facebook.oauth2
  • fastify.oauth2Github.oauth2
  • fastify.oauth2Spotify.oauth2
  • fastify.oauth2Vkontakte.oauth2

假设我们已经注册了多个 OAuth 供应商:

  • fastify.register(oauthPlugin, { name: 'facebook', { ... } // facebooks credentials, startRedirectPath, callbackUri etc )
  • fastify.register(oauthPlugin, { name: 'github', { ... } // githubs credentials, startRedirectPath, callbackUri etc )
  • fastify.register(oauthPlugin, { name: 'spotify', { ... } // spotifys credentials, startRedirectPath, callbackUri etc )
  • fastify.register(oauthPlugin, { name: 'vkontakte', { ... } // vkontaktes credentials, startRedirectPath, callbackUri etc )

公用事业

此加固插件为您的加固实例添加了 6 个功能装饰器 命名空间数字 :

  • getAccessTokenFromAuthorizationCodeFlow(request, callback): 使用授权代码流来取取 OAuth2 令牌的函数,它使用该流的最后一个请求中的数据. 如果召回没有通过,它会返回一个承诺。 回调或承诺解析返回 访问脚本 对象,该对象具有 AccessToken.token 带有下列密钥的属性:

    • access_token
    • refresh_token (可选,只有在 offline scope 最初请求,如回调UriParams的例子所示)
    • token_type (一般为: 'Bearer'(中文(简体) )
    • expires_in (令牌过期的秒数,例如. 240000(中文(简体) )
  • 或 getAccessTokenFromAuthorizationCodeFlow(request, reply, callback) 有3个参数的变体,这是PKCE扩展使用时建议的形式和要求. 通过 reply 允许快取-oaut2删除状态和 PKCE 代码 验证器 cookie,这样,如果服务器在取出令牌时有问题,那么它们就不会留在浏览器中,这样已经到达回调状态就不能被重放. 见 以 PKCE 为例 Google 更多。 。 。 .

    必须指出: 如果您的提供者支持 S256 作为代码-挑战 方法,总是更喜欢这样. 仅使用 plain 当你的提供者不支持 S256。 。 。 .

  • getNewAccessTokenUsingRefreshToken(token, params, callback):取去平面符号对象(即 token 财产 AccessToken 对象,或带有 refresh_token 获取新的 AccessToken- 目标 这对背景处理人员来说,在之前的 AccessToken 过期时重新发布新的 AccessToken 非常有用. 这个 params 参数是可选的,它是一个可以用来在附加参数中传递到刷新请求(例如更严格的一组范围)的对象。 如果回调未通过, 此函数将返回一个承诺 。 由召回或解约产生的对象是新的 AccessToken 对象(见上文)。 你如何使用它的例子 name:googleOAuth2数字 :

fastify.googleOAuth2.getNewAccessTokenUsingRefreshToken(currentAccessToken.token, {}, (err, newAccessToken) => {
   // Handle the new accessToken, e.g. newAccessToken.token.access_token
});
  • generateAuthorizationUri(requestObject, replyObject, callback): 生成授权 uri 的函数。 如果回调未通过, 此函数将返回一个承诺 。 由回调或解约产生的字符串是ur授权. 当您想要在特定的路线中处理方向调整时, 这一般是有用的 。 这个 requestObject 参数将请求对象传递到 generateStateFunction) (中文(简体) ). 你个 别 需要声明 startRedirectPath 如果你使用这个方法。 你如何使用它的例子:
fastify.get('/external', { /* Hooks can be used here */ }, (req, reply) => {
  fastify.oauth2CustomOAuth2.generateAuthorizationUri(req, reply, (err, authorizationEndpoint) => {
    reply.redirect(authorizationEndpoint)
  });
});
  • revokeToken(Token, tokenType, params, callback): 在授权服务器上取消当前访问 ken 或刷新 token 的功能 。 如果召回没有通过,它会返回一个承诺。 回拨或承诺解析返回 void
fastify.googleOAuth2.revokeToken(currentAccessToken, 'access_token', undefined, (err) => {
   // Handle the reply here
});
  • revokeAllToken(Token, params, callback): 取消授权服务器上当前访问的功能 token并刷新 token 。 如果召回没有通过,它会返回一个承诺。 回拨或承诺解析返回 void
fastify.googleOAuth2.revokeAllToken(currentAccessToken, undefined, (err) => {
   // Handle the reply here
});
  • userinfo(tokenOrTokenSet): 从授权提供者获取用户信息数据的函数 。 两种符号(作为对象)或 access_token 字符串值可以传递 .

重要说明: 用户信息只在 discovery 选项被使用,身份提供者则发布此类终点广告.

对于静态配置的插件,您需要让 HTTP 给自己打电话 .

详见OIDC标准定义 用户信息端点

更多见 userinfo_endpoint 属性在 OIDC 发现元数据 标准定义.

fastify.googleOAuth2.userinfo(currentAccessToken, (err, userinfo) => {
   // do something with userinfo
});
// with custom params
fastify.googleOAuth2.userinfo(currentAccessToken, { method: 'GET', params: { /* add your custom key value pairs here to be appended to request */ } },  (err, userinfo) => {
   // do something with userinfo
});

// or promise version
const userinfo = await fastify.googleOAuth2.userinfo(currentAccessToken);
// use custom params
const userinfo = await fastify.googleOAuth2.userinfo(currentAccessToken, { method: 'GET', params: { /* ... */ } });

有一些变体带有召回和许诺. 自定义参数可以作为选项传递. 见 类型 使用模式 实例。 。 。 .

说明:

我们支持HTTP GET 财务报告和审定财务报表 POST 请求使用 userinfo 端点发送访问令牌 Bearer 头部有计划. 您可以通过设置来做到这一点( C)via: "header" 参数),但因其为默认值而并非强制.

我们也支持 POST 发送 access_token 在一个请求机构。 您可以明确提供 via: "body" 参数.

例如,用于 name: 'customOauth2',帮助者 getAccessTokenFromAuthorizationCodeFlow 财务报告和审定财务报表 getNewAccessTokenUsingRefreshToken 将像这样可以访问:

  • fastify.oauth2CustomOauth2.getAccessTokenFromAuthorizationCodeFlow
  • fastify.oauth2CustomOauth2.getNewAccessTokenUsingRefreshToken

使用类型脚本

类型定义随包而提供. 装饰在运行期间被应用并基于认证配置名. 一个解决方案是利用TypeScript声明合并来添加类型安全命名空间. 确保你有 @types/node 已安装以正确工作 .

在项目申报文件中

import { OAuth2Namespace } from '@fastify/oauth2';

declare module 'fastify' {
  interface FastifyInstance {
    facebookOAuth2: OAuth2Namespace;
    myCustomOAuth2: OAuth2Namespace;
  }
}

所有认证配置可用 oauth2 键入到 OAuth2Namespace | undefined比如说, eg. fastify.oauth2CustomOauth2 页:1 customOauth2。 。 。 .

提供方

下列提供者要求正确安排额外工作.

抖动

Twitch 要求在 oauth2 流中求取一个符号必须包含 client_id 财务报告和审定财务报表 client_secret 属性在 tokenRequestParams数字 :

fastify.register(oauthPlugin, {
  name: 'twitchOauth2',
  credentials: {
    client: {
      id: '<CLIENT_ID>',
      secret: '<CLIENT_SECRET>'
    },
    auth: oauthPlugin.TWITCH_CONFIGURATION
  },
  tokenRequestParams: {
    client_id: '<CLIENT_ID>',
    client_secret: '<CLIENT_SECRET>',
  },
  // register a fastify url to start the redirect flow
  startRedirectPath: '/login/twitch',
  // twitch redirect here after the user login
  callbackUri: 'http://localhost:3000/login/twitch/callback'
})

链接

链接信息也要求 client_id 财务报告和审定财务报表 client_secret 在符号请求正文中,否则符号交换失败 400 Bad Request通过 tokenRequestParams 如上文Twitch所示。 见 实例/链接.js。 。 。 .

许可证

许可证根据 麻省理工学院。 。 。 .

编号 见 simple-oauth2 驾照也是

版本与发布记录

@fastify/oauth2 共发布 31 个版本,首次发布于 2022/04/27;过去 12 个月发布了 5 个版本。最新版本附带 npm provenance 构建来源证明,可追溯到公开的 CI 构建记录。

版本发布日期距今
8.3.2latest2026/10/1926 天前
8.3.12026/10/101 个月前
8.3.02026/08/152 个月前
8.2.12026/08/083 个月前
8.2.02026/02/109 个月前
8.1.22025/02/101.8 年前

其他发布通道:next → 8.0.0。

关于 @fastify/oauth2 的常见问题

@fastify/oauth2 是什么?

使用 oaut2 协议进行登录

如何安装 @fastify/oauth2?

在项目目录运行 npm install @fastify/oauth2,或使用 pnpm add / yarn add / bun add。

@fastify/oauth2 支持 TypeScript 吗?

支持。包内自带 TypeScript 类型声明(package.json 声明了 types 入口),安装后即可获得类型提示,无需再安装 @types 包。

@fastify/oauth2 支持 ESM 还是 CommonJS?

以 CommonJS 形式发布,可以直接 require();在 ES Module 项目中也可以用 import 引入(Node.js 会把 module.exports 作为默认导出)。

@fastify/oauth2 可以商用吗?

@fastify/oauth2 使用 MIT 许可。宽松许可:允许商业使用、修改和再分发,通常只需在分发时保留原版权与许可声明。以上为概括,不构成法律意见,请以许可原文为准。

@fastify/oauth2 的下载量有多少?

根据 npm 官方下载统计,@fastify/oauth2 在 2026/10/15 – 2026/11/13 这 30 天内被下载 424,851 次,日均约 14,162 次。下载量会把 CI 构建、镜像同步和作为其他包依赖的安装一并计入,适合横向比较热度,不能直接等同于使用人数。

@fastify/oauth2 还在维护吗?

最新版本 8.3.2 发布于 2026/10/19(26 天前);至今共发布 31 个版本,其中过去 12 个月发布了 5 个;首次发布于 2022/04/27。发布频率只是参考信号:功能稳定的工具可能很少需要更新,建议结合源码仓库的 issue 和提交记录判断。