npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@idevless/nuxt-auth

v1.0.4

Published

Nuxt OAuth

Readme

Nuxt OAuth

npm version npm downloads License

一个简单易用的 Nuxt OAuth 认证模块,支持多种主流 OAuth 提供商。

✨ 特性

  • 🛡️ 内置 CSRF 保护(基于 cookie 的状态验证)
  • 📦 TypeScript 支持
  • 🎯 简单的配置和使用

📦 安装

# 使用 Nuxi 添加模块(推荐)
npx nuxi module add @idevless/nuxt-oauth

# 或者手动安装
npm install @idevless/nuxt-oauth
# yarn add @idevless/nuxt-oauth
# pnpm add @idevless/nuxt-oauth

🚀 快速开始

1. 添加模块到 Nuxt 配置

// nuxt.config.ts
export default defineNuxtConfig({
  modules: ['@idevless/nuxt-oauth'],
  runtimeConfig: {
    oauth: {
      enableState: true, // 启用 CSRF 保护
      defaultCallbackPath: '/', // 认证成功后的默认跳转路径
      providers: {
        github: {
          clientId: process.env.GITHUB_CLIENT_ID,
          clientSecret: process.env.GITHUB_CLIENT_SECRET,
          scopes: ['user:email'] // 可选,默认为空数组
        },
        feishu: {
          clientId: process.env.FEISHU_CLIENT_ID,
          clientSecret: process.env.FEISHU_CLIENT_SECRET,
          scopes: [] // 可选
        }
      }
    }
  }
})

2. 创建 OAuth 路由处理器

授权入口路由

创建 server/routes/oauth/[provider].get.ts

export default defineGatewayEventHandler({
  // 可选:重定向前的回调
  onBeforeRedirect: (event, { providerName, state }) => {
    console.log(`准备跳转到 ${providerName} 进行授权`)
  },
  // 可选:错误处理
  onError: (event, error) => {
    console.error('OAuth 授权错误:', error)
  }
})

回调路由

创建 server/routes/oauth/callback/[provider].get.ts

export default defineCallbackEventHandler({
  // 认证成功回调
  onSuccess: (event, { providerName, tokenData, userInfo, state }) => {
    console.log('认证成功:', {
      provider: providerName,
      user: userInfo,
      token: tokenData
    })

    // 在这里可以:
    // 1. 将用户信息保存到数据库
    // 2. 创建会话
    // 3. 设置 JWT token
    // 4. 其他业务逻辑
  },
  // 可选:错误处理
  onError: (event, error) => {
    console.error('OAuth 回调错误:', error)
    // 重定向到错误页面
    return sendRedirect(event, '/?error=' + encodeURIComponent(error.message))
  }
})

3. 在前端创建登录链接

<template>
  <div>
    <h1>登录</h1>
    <a href="/oauth/github" class="btn">使用 GitHub 登录</a>
    <a href="/oauth/feishu" class="btn">使用飞书登录</a>
  </div>
</template>

🔧 配置选项

运行时配置

interface RuntimeConfig {
  oauth: {
    enableState?: boolean // 是否启用 CSRF 保护,默认 false
    defaultCallbackPath?: string // 认证成功后的默认跳转路径,默认 '/'
    providers: {
      [providerName: string]: {
        clientId: string
        clientSecret: string
        scopes?: string[] // OAuth 作用域,默认为空数组
      }
    }
  }
}

环境变量

推荐使用环境变量来配置敏感信息:

# .env
GITHUB_CLIENT_ID=your_github_client_id
GITHUB_CLIENT_SECRET=your_github_client_secret
FEISHU_CLIENT_ID=your_feishu_client_id
FEISHU_CLIENT_SECRET=your_feishu_client_secret

📚 支持的提供商

GitHub

// 用户信息类型
interface GitHubUser {
  id: number
  name: string | null
  avatar_url: string
  email: string | null
  login: string
  url: string
}

// Token 信息类型
interface GitHubToken {
  access_token: string
  token_type: string
  scope: string
}

配置 GitHub OAuth 应用:

  1. 访问 GitHub Developer Settings
  2. 创建新的 OAuth 应用
  3. 设置回调 URL:http://localhost:3000/oauth/callback/github

飞书 (Feishu)

// 用户信息类型
interface FeishuUser {
  user_id: string
  open_id: string
  union_id: string
  name?: string
  en_name?: string
  avatar_url: string
  email?: string
  mobile?: string
  tenent_key?: string
  enterprise_email?: string
  employee_no?: string
}

// Token 信息类型
interface FeishuToken {
  access_token: string
  expires_in: number
  refresh_token?: string
  refresh_token_expires_in?: number
  scope: string
}

配置飞书 OAuth 应用:

  1. 访问 飞书开放平台
  2. 创建企业自建应用
  3. 配置重定向 URL:http://localhost:3000/oauth/callback/feishu

🔒 安全性

CSRF 保护

启用 enableState: true 来开启 CSRF 保护:

// nuxt.config.ts
export default defineNuxtConfig({
  runtimeConfig: {
    oauth: {
      enableState: true // 启用状态验证
      // ...
    }
  }
})

当启用状态验证时,模块会:

  1. 在授权请求中生成随机 state 参数
  2. 将 state 存储在 HTTP-only cookie 中
  3. 在回调中验证 state 参数是否匹配

Cookie 安全

State cookie 的安全配置:

  • httpOnly: 在 HTTPS 环境下自动启用
  • secure: 在 HTTPS 环境下自动启用
  • sameSite: 设置为 'lax'
  • maxAge: 10 分钟过期

🛠️ 高级用法

自定义错误处理

export default defineCallbackEventHandler({
  onError: async (event, error) => {
    // 记录错误日志
    console.error('OAuth 认证失败:', error)

    // 重定向到自定义错误页面
    return sendRedirect(event, `/auth/error?message=${encodeURIComponent(error.message)}`)
  }
})

会话管理集成

export default defineCallbackEventHandler({
  onSuccess: async (event, { userInfo, tokenData }) => {
    // 创建用户会话
    const session = await createUserSession({
      userId: userInfo.id,
      email: userInfo.email,
      accessToken: tokenData.access_token
    })

    // 设置会话 cookie
    setCookie(event, 'session', session.id, {
      httpOnly: true,
      secure: true,
      maxAge: 86400 // 24 小时
    })
  }
})

数据库集成

export default defineCallbackEventHandler({
  onSuccess: async (event, { providerName, userInfo, tokenData }) => {
    // 查找或创建用户
    let user = await findUserByEmail(userInfo.email)

    if (!user) {
      user = await createUser({
        email: userInfo.email,
        name: userInfo.name,
        avatar: userInfo.avatar_url,
        provider: providerName
      })
    }

    // 更新或创建 OAuth 连接
    await upsertOAuthConnection({
      userId: user.id,
      provider: providerName,
      providerId: userInfo.id.toString(),
      accessToken: tokenData.access_token
    })
  }
})

🧪 开发和测试

运行示例项目

# 安装依赖
npm install

# 启动开发服务器
npm run dev

访问 http://localhost:3000 查看示例应用。

测试

# 运行测试
npm run test

# 监听模式
npm run test:watch

🤝 贡献

欢迎提交 Issue 和 Pull Request!

📄 许可证

MIT License

🔗 相关链接