{"_id":"@alex-axe/nuxt-auth","_rev":"2-70de12eb5e3e6b8f5b532da0bac48431","name":"@alex-axe/nuxt-auth","dist-tags":{"latest":"2.0.1"},"versions":{"1.1.1":{"name":"@alex-axe/nuxt-auth","version":"1.1.1","keywords":["nuxt","auth","authentication","authorization"],"author":{"name":"idevless"},"license":"MIT","_id":"@alex-axe/nuxt-auth@1.1.1","maintainers":[{"name":"alex-axe","email":"phone15570631351@gmail.com"}],"homepage":"https://github.com/idevless/nuxt-auth","bugs":{"url":"https://github.com/idevless/nuxt-auth/issues"},"dist":{"shasum":"445e4894cc2fe0899b15a50171a8fe77d46581f1","tarball":"https://registry.npmjs.org/@alex-axe/nuxt-auth/-/nuxt-auth-1.1.1.tgz","fileCount":24,"integrity":"sha512-/+RWsyMeV+9t5UT0TpAgDOBEKugbOZAGWkex1qFB9GtDTGzJouKExdaWO/DI16NAm/gOni17hRwGNQPAAcdxMA==","signatures":[{"sig":"MEQCIDE29bj+o+xHmt4mnnN8sA49yiRUULsDvtZ5PMfFVsqiAiAsJQQnQTkyyKF1j8miWOP77yybAjCyVAa0Jw3X52GF6g==","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":39861},"main":"./dist/module.mjs","type":"module","exports":{".":{"types":"./dist/types.d.mts","import":"./dist/module.mjs"}},"gitHead":"19c779560d61b1b867aef0c416a93ab512c53fd9","scripts":{"dev":"npm run dev:prepare && nuxi dev playground","lint":"eslint .","test":"vitest run","prepack":"nuxt-module-build build","release":"npm run lint && npm run test && npm run prepack && changelogen --release && npm publish && git push --follow-tags","dev:build":"nuxi build playground","test:types":"vue-tsc --noEmit && cd playground && vue-tsc --noEmit","test:watch":"vitest watch","dev:prepare":"nuxt-module-build build --stub && nuxt-module-build prepare && nuxi prepare playground"},"_npmUser":{"name":"alex-axe","email":"phone15570631351@gmail.com"},"repository":{"url":"git+https://github.com/idevless/nuxt-auth.git","type":"git"},"_npmVersion":"11.3.0","description":"Nuxt 身份鉴权模块","directories":{},"_nodeVersion":"20.19.0","dependencies":{"@nuxt/kit":"^4.1.1"},"typesVersions":{"*":{".":["./dist/types.d.mts"]}},"_hasShrinkwrap":false,"packageManager":"yarn@1.22.22+sha512.a6b2f7906b721bba3d67d4aff083df04dad64c399707841b7acf00f6b133b7ac24255f2652fa22ae3534329dc6180534e98d17432037ff6fd140556e2bb3137e","devDependencies":{"nuxt":"^4.1.1","eslint":"^9.35.0","vitest":"^3.2.4","vue-tsc":"^3.0.6","@nuxt/ui":"4.0.0-alpha.1","@nuxt/icon":"2.0.0","typescript":"~5.9.2","@types/node":"latest","changelogen":"^0.6.2","@nuxt/schema":"^4.1.1","@nuxt/devtools":"^2.6.3","@nuxt/test-utils":"^3.19.2","@nuxt/eslint-config":"^1.9.0","@nuxt/module-builder":"^1.0.2"},"_npmOperationalInternal":{"tmp":"tmp/nuxt-auth_1.1.1_1757680507153_0.3191190463019269","host":"s3://npm-registry-packages-npm-production"}},"2.0.1":{"name":"@alex-axe/nuxt-auth","version":"2.0.1","description":"Nuxt OAuth","repository":{"type":"git","url":"git+https://github.com/idevless/nuxt-oauth.git"},"author":{"name":"idevless"},"keywords":["nuxt","oauth","nuxt-oauth"],"homepage":"https://github.com/idevless/nuxt-oauth","bugs":{"url":"https://github.com/idevless/nuxt-oauth/issues"},"engines":{"node":">=18"},"license":"MIT","type":"module","exports":{".":{"types":"./dist/types.d.mts","import":"./dist/module.mjs"}},"main":"./dist/module.mjs","typesVersions":{"*":{".":["./dist/types.d.mts"]}},"scripts":{"dev":"npm run dev:prepare && nuxi dev playground","dev:build":"nuxi build playground","dev:prepare":"nuxt-module-build build --stub && nuxt-module-build prepare && nuxi prepare playground","release":"changelogen --release && npm publish && git push --follow-tags","lint":"eslint .","test":"vitest run","test:watch":"vitest watch","test:types":"vue-tsc --noEmit && cd playground && vue-tsc --noEmit"},"dependencies":{"@nuxt/kit":"^4.1.1","zod":"^4.1.9"},"devDependencies":{"@nuxt/devtools":"^2.6.3","@nuxt/eslint-config":"^1.9.0","@nuxt/module-builder":"^1.0.2","@nuxt/schema":"^4.1.1","@nuxt/test-utils":"^3.19.2","@nuxt/ui":"^4.0.0-alpha.1","@types/node":"latest","changelogen":"^0.6.2","eslint":"^9.35.0","nuxt":"^4.1.1","type-fest":"^5.0.0","typescript":"~5.9.2","vitest":"^3.2.4","vue-tsc":"^3.0.6"},"packageManager":"yarn@1.22.22+sha512.a6b2f7906b721bba3d67d4aff083df04dad64c399707841b7acf00f6b133b7ac24255f2652fa22ae3534329dc6180534e98d17432037ff6fd140556e2bb3137e","_id":"@alex-axe/nuxt-auth@2.0.1","gitHead":"c8360584dbda7cc5cc0d1d361af08d058aefeeb7","_nodeVersion":"20.19.0","_npmVersion":"11.3.0","dist":{"integrity":"sha512-L7ANQqhKihBxUCcHCuqZXQqBGG5msjzL2oG0/5B11629bU6VNRgoI0EWTaG9FDBN+jL/bwJh3Io5Bz070LiU9A==","shasum":"87c6218f2b133f7710f91a0556082f3e961aef4e","tarball":"https://registry.npmjs.org/@alex-axe/nuxt-auth/-/nuxt-auth-2.0.1.tgz","fileCount":20,"unpackedSize":24850,"signatures":[{"keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U","sig":"MEUCIAksLEdPp2XDdaewz9IAuFoGhkxquR5FKi4kckDonvFoAiEA69BnP/91pdpfcaJYp0MM1vrFmog+b8bOH4LDPnvioPM="}]},"_npmUser":{"name":"alex-axe","email":"phone15570631351@gmail.com"},"directories":{},"maintainers":[{"name":"alex-axe","email":"phone15570631351@gmail.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages-npm-production","tmp":"tmp/nuxt-auth_2.0.1_1758140130181_0.01979079206581269"},"_hasShrinkwrap":false}},"time":{"created":"2025-09-12T12:35:07.064Z","modified":"2025-09-17T20:15:30.549Z","1.1.1":"2025-09-12T12:35:07.344Z","2.0.1":"2025-09-17T20:15:30.367Z"},"bugs":{"url":"https://github.com/idevless/nuxt-oauth/issues"},"author":{"name":"idevless"},"license":"MIT","homepage":"https://github.com/idevless/nuxt-oauth","keywords":["nuxt","oauth","nuxt-oauth"],"repository":{"type":"git","url":"git+https://github.com/idevless/nuxt-oauth.git"},"description":"Nuxt OAuth","maintainers":[{"name":"alex-axe","email":"phone15570631351@gmail.com"}],"readme":"# Nuxt OAuth\n\n[![npm version][npm-version-src]][npm-version-href]\n[![npm downloads][npm-downloads-src]][npm-downloads-href]\n[![License][license-src]][license-href]\n\n一个简单易用的 Nuxt OAuth 认证模块，支持多种主流 OAuth 提供商。\n\n## ✨ 特性\n\n- 🛡️ 内置 CSRF 保护（基于 cookie 的状态验证）\n- 📦 TypeScript 支持\n- 🎯 简单的配置和使用\n\n## 📦 安装\n\n```bash\n# 使用 Nuxi 添加模块（推荐）\nnpx nuxi module add @idevless/nuxt-oauth\n\n# 或者手动安装\nnpm install @idevless/nuxt-oauth\n# yarn add @idevless/nuxt-oauth\n# pnpm add @idevless/nuxt-oauth\n```\n\n## 🚀 快速开始\n\n### 1. 添加模块到 Nuxt 配置\n\n```typescript\n// nuxt.config.ts\nexport default defineNuxtConfig({\n  modules: ['@idevless/nuxt-oauth'],\n  runtimeConfig: {\n    oauth: {\n      enableState: true, // 启用 CSRF 保护\n      defaultCallbackPath: '/', // 认证成功后的默认跳转路径\n      providers: {\n        github: {\n          clientId: process.env.GITHUB_CLIENT_ID,\n          clientSecret: process.env.GITHUB_CLIENT_SECRET,\n          scopes: ['user:email'] // 可选，默认为空数组\n        },\n        feishu: {\n          clientId: process.env.FEISHU_CLIENT_ID,\n          clientSecret: process.env.FEISHU_CLIENT_SECRET,\n          scopes: [] // 可选\n        }\n      }\n    }\n  }\n})\n```\n\n### 2. 创建 OAuth 路由处理器\n\n#### 授权入口路由\n\n创建 `server/routes/oauth/[provider].get.ts`：\n\n```typescript\nexport default defineGatewayEventHandler({\n  // 可选：重定向前的回调\n  onBeforeRedirect: (event, { providerName, state }) => {\n    console.log(`准备跳转到 ${providerName} 进行授权`)\n  },\n  // 可选：错误处理\n  onError: (event, error) => {\n    console.error('OAuth 授权错误:', error)\n  }\n})\n```\n\n#### 回调路由\n\n创建 `server/routes/oauth/callback/[provider].get.ts`：\n\n```typescript\nexport default defineCallbackEventHandler({\n  // 认证成功回调\n  onSuccess: (event, { providerName, tokenData, userInfo, state }) => {\n    console.log('认证成功:', {\n      provider: providerName,\n      user: userInfo,\n      token: tokenData\n    })\n\n    // 在这里可以：\n    // 1. 将用户信息保存到数据库\n    // 2. 创建会话\n    // 3. 设置 JWT token\n    // 4. 其他业务逻辑\n  },\n  // 可选：错误处理\n  onError: (event, error) => {\n    console.error('OAuth 回调错误:', error)\n    // 重定向到错误页面\n    return sendRedirect(event, '/?error=' + encodeURIComponent(error.message))\n  }\n})\n```\n\n### 3. 在前端创建登录链接\n\n```vue\n<template>\n  <div>\n    <h1>登录</h1>\n    <a href=\"/oauth/github\" class=\"btn\">使用 GitHub 登录</a>\n    <a href=\"/oauth/feishu\" class=\"btn\">使用飞书登录</a>\n  </div>\n</template>\n```\n\n## 🔧 配置选项\n\n### 运行时配置\n\n```typescript\ninterface RuntimeConfig {\n  oauth: {\n    enableState?: boolean // 是否启用 CSRF 保护，默认 false\n    defaultCallbackPath?: string // 认证成功后的默认跳转路径，默认 '/'\n    providers: {\n      [providerName: string]: {\n        clientId: string\n        clientSecret: string\n        scopes?: string[] // OAuth 作用域，默认为空数组\n      }\n    }\n  }\n}\n```\n\n### 环境变量\n\n推荐使用环境变量来配置敏感信息：\n\n```bash\n# .env\nGITHUB_CLIENT_ID=your_github_client_id\nGITHUB_CLIENT_SECRET=your_github_client_secret\nFEISHU_CLIENT_ID=your_feishu_client_id\nFEISHU_CLIENT_SECRET=your_feishu_client_secret\n```\n\n## 📚 支持的提供商\n\n### GitHub\n\n```typescript\n// 用户信息类型\ninterface GitHubUser {\n  id: number\n  name: string | null\n  avatar_url: string\n  email: string | null\n  login: string\n  url: string\n}\n\n// Token 信息类型\ninterface GitHubToken {\n  access_token: string\n  token_type: string\n  scope: string\n}\n```\n\n**配置 GitHub OAuth 应用：**\n\n1. 访问 [GitHub Developer Settings](https://github.com/settings/developers)\n2. 创建新的 OAuth 应用\n3. 设置回调 URL：`http://localhost:3000/oauth/callback/github`\n\n### 飞书 (Feishu)\n\n```typescript\n// 用户信息类型\ninterface FeishuUser {\n  user_id: string\n  open_id: string\n  union_id: string\n  name?: string\n  en_name?: string\n  avatar_url: string\n  email?: string\n  mobile?: string\n  tenent_key?: string\n  enterprise_email?: string\n  employee_no?: string\n}\n\n// Token 信息类型\ninterface FeishuToken {\n  access_token: string\n  expires_in: number\n  refresh_token?: string\n  refresh_token_expires_in?: number\n  scope: string\n}\n```\n\n**配置飞书 OAuth 应用：**\n\n1. 访问 [飞书开放平台](https://open.feishu.cn/)\n2. 创建企业自建应用\n3. 配置重定向 URL：`http://localhost:3000/oauth/callback/feishu`\n\n## 🔒 安全性\n\n### CSRF 保护\n\n启用 `enableState: true` 来开启 CSRF 保护：\n\n```typescript\n// nuxt.config.ts\nexport default defineNuxtConfig({\n  runtimeConfig: {\n    oauth: {\n      enableState: true // 启用状态验证\n      // ...\n    }\n  }\n})\n```\n\n当启用状态验证时，模块会：\n\n1. 在授权请求中生成随机 state 参数\n2. 将 state 存储在 HTTP-only cookie 中\n3. 在回调中验证 state 参数是否匹配\n\n### Cookie 安全\n\nState cookie 的安全配置：\n\n- `httpOnly`: 在 HTTPS 环境下自动启用\n- `secure`: 在 HTTPS 环境下自动启用\n- `sameSite`: 设置为 'lax'\n- `maxAge`: 10 分钟过期\n\n## 🛠️ 高级用法\n\n### 自定义错误处理\n\n```typescript\nexport default defineCallbackEventHandler({\n  onError: async (event, error) => {\n    // 记录错误日志\n    console.error('OAuth 认证失败:', error)\n\n    // 重定向到自定义错误页面\n    return sendRedirect(event, `/auth/error?message=${encodeURIComponent(error.message)}`)\n  }\n})\n```\n\n### 会话管理集成\n\n```typescript\nexport default defineCallbackEventHandler({\n  onSuccess: async (event, { userInfo, tokenData }) => {\n    // 创建用户会话\n    const session = await createUserSession({\n      userId: userInfo.id,\n      email: userInfo.email,\n      accessToken: tokenData.access_token\n    })\n\n    // 设置会话 cookie\n    setCookie(event, 'session', session.id, {\n      httpOnly: true,\n      secure: true,\n      maxAge: 86400 // 24 小时\n    })\n  }\n})\n```\n\n### 数据库集成\n\n```typescript\nexport default defineCallbackEventHandler({\n  onSuccess: async (event, { providerName, userInfo, tokenData }) => {\n    // 查找或创建用户\n    let user = await findUserByEmail(userInfo.email)\n\n    if (!user) {\n      user = await createUser({\n        email: userInfo.email,\n        name: userInfo.name,\n        avatar: userInfo.avatar_url,\n        provider: providerName\n      })\n    }\n\n    // 更新或创建 OAuth 连接\n    await upsertOAuthConnection({\n      userId: user.id,\n      provider: providerName,\n      providerId: userInfo.id.toString(),\n      accessToken: tokenData.access_token\n    })\n  }\n})\n```\n\n## 🧪 开发和测试\n\n### 运行示例项目\n\n```bash\n# 安装依赖\nnpm install\n\n# 启动开发服务器\nnpm run dev\n```\n\n访问 `http://localhost:3000` 查看示例应用。\n\n### 测试\n\n```bash\n# 运行测试\nnpm run test\n\n# 监听模式\nnpm run test:watch\n```\n\n## 🤝 贡献\n\n欢迎提交 Issue 和 Pull Request！\n\n## 📄 许可证\n\n[MIT License](./LICENSE)\n\n## 🔗 相关链接\n\n- [Nuxt 3 文档](https://nuxt.com/)\n- [H3 文档](https://github.com/unjs/h3)\n- [GitHub OAuth 文档](https://docs.github.com/en/developers/apps/building-oauth-apps)\n- [飞书 OAuth 文档](https://open.feishu.cn/document/ukTMukTMukTM/ukzN4UjL5cDO14SO3gTN)\n\n<!-- Badges -->\n\n[npm-version-src]: https://img.shields.io/npm/v/@idevless/nuxt-oauth/latest.svg?style=flat&colorA=18181B&colorB=28CF8D\n[npm-version-href]: https://npmjs.com/package/@idevless/nuxt-oauth\n[npm-downloads-src]: https://img.shields.io/npm/dm/@idevless/nuxt-oauth.svg?style=flat&colorA=18181B&colorB=28CF8D\n[npm-downloads-href]: https://npmjs.com/package/@idevless/nuxt-oauth\n[license-src]: https://img.shields.io/npm/l/@idevless/nuxt-oauth.svg?style=flat&colorA=18181B&colorB=28CF8D\n[license-href]: https://npmjs.com/package/@idevless/nuxt-oauth\n","readmeFilename":"README.md"}