nodeops-auth
Compare original and translation side by side
🇺🇸
Original
English🇨🇳
Translation
ChineseNodeOps Auth Setup
NodeOps 认证设置
Add NodeOps PKCE OAuth to an existing Next.js (App Router) project.
为现有Next.js(App Router)项目添加NodeOps PKCE OAuth。
Prerequisites
前置条件
Before starting, verify the project is compatible:
- App Router required: Check if directory exists. If only
app/exists, stop and tell the user: "This skill only supports Next.js App Router. Your project uses Pages Router."pages/ - Next.js required: Check for
package.jsonin dependencies. If missing, stop and tell the user this is a Next.js-only package.next
开始前请确认项目兼容性:
- 必须使用App Router:检查是否存在目录。如果仅存在
app/目录,停止操作并告知用户:"本技能仅支持Next.js App Router,你的项目使用的是Pages Router。"pages/ - 必须是Next.js项目:检查的依赖项中是否包含
package.json。如果缺失,停止操作并告知用户这是仅适用于Next.js的包。next
Idempotency
幂等性处理
Before each step, check if the work is already done. Skip steps that are already complete:
- If is already in
@nodeops-createos/integration-oauthdependencies, skip install.package.json - If (or
app/api/auth/[...nodeops]/route.ts) already exists, skip route creation..js - If from
AuthProvideris already imported in the layout, skip wrapping.@nodeops-createos/integration-oauth - If (or
app/callback/page.tsx) already exists, skip callback page creation..jsx - If already exists and contains
.env.example, skip env file creation.NODEOPS_
每步操作前先检查是否已经完成,跳过已完成的步骤:
- 如果已经在
@nodeops-createos/integration-oauth依赖项中,跳过安装步骤。package.json - 如果(或
app/api/auth/[...nodeops]/route.ts)已存在,跳过路由创建步骤。.js - 如果的
@nodeops-createos/integration-oauth已经在布局文件中导入,跳过包裹步骤。AuthProvider - 如果(或
app/callback/page.tsx)已存在,跳过回调页创建步骤。.jsx - 如果已存在且包含
.env.example前缀变量,跳过环境变量文件创建步骤。NODEOPS_
Steps
操作步骤
-
Detect project setup — readand check for lock files:
package.json- Package manager: if exists → pnpm, if
pnpm-lock.yamlexists → yarn, else → npmyarn.lock - TypeScript: if exists use
tsconfig.json/.tsextensions, else.tsx/.js.jsx - Confirm directory exists (App Router). If only
app/exists, stop.pages/ - Confirm is in dependencies. If not, stop.
next
- Package manager: if
-
Install the package — run the appropriate install command:
- npm:
npm install @nodeops-createos/integration-oauth - pnpm:
pnpm add @nodeops-createos/integration-oauth - yarn:
yarn add @nodeops-createos/integration-oauth - If install fails: check if the user has network access and the registry is reachable. Suggest running the command manually if it keeps failing.
- npm:
-
Create the catch-all API route — create(or
app/api/auth/[...nodeops]/route.ts), creating directories as needed:.jstsexport { GET, POST } from '@nodeops-createos/integration-oauth/server'; -
Wrap layout with AuthProvider — read the root layout file. It could be,
app/layout.tsx,app/layout.jsx, orapp/layout.js. Find whichever exists.app/layout.ts- Add the import at the top of the file:
tsx
import { AuthProvider } from '@nodeops-createos/integration-oauth'; - Find inside the
{children}tag. Wrap it with<body>:<AuthProvider>tsx<AuthProvider>{children}</AuthProvider> - Do NOT add "use client" to the layout. is already marked
AuthProviderinternally — it works fine when imported from a Server Component layout."use client" - If the layout already has other providers (e.g., ThemeProvider, QueryClientProvider), nest alongside them. Do NOT remove or replace existing providers.
<AuthProvider> - If is not directly inside
{children}(e.g., it's inside a wrapper div or fragment), wrap wherever<body>appears.{children} - If no layout file exists, stop and tell the user to create a root layout first.
- Add the import at the top of the file:
-
Create the callback page — ask the user: "Where should users be redirected after login? (default: /dashboard)". Use their answer as thevalue. Then create
redirectTo(orapp/callback/page.tsx):.jsxtsx"use client"; import { useCallbackHandler } from "@nodeops-createos/integration-oauth"; export default function Callback() { const { loading, error } = useCallbackHandler({ redirectTo: "/dashboard" }); if (loading) return ( <div style={{ display: "flex", justifyContent: "center", alignItems: "center", height: "100vh" }}> <p>Signing in...</p> </div> ); if (error) return <p>Login failed: {error}</p>; return null; } -
Create— create this file at the project root:
.env.example# ── Client-side (exposed to browser via NEXT_PUBLIC_ prefix) ────────────────── NEXT_PUBLIC_NODEOPS_AUTH_URL=https://id.nodeops.network/oauth2/auth NEXT_PUBLIC_NODEOPS_CLIENT_ID=your_client_id_here NEXT_PUBLIC_NODEOPS_REDIRECT_URI=http://localhost:3000/callback NEXT_PUBLIC_NODEOPS_SCOPES=offline_access offline openid # ── Server-side only (never sent to browser) ────────────────────────────────── NODEOPS_CLIENT_SECRET=your_client_secret_here NODEOPS_TOKEN_URL=https://id.nodeops.network/oauth2/token NODEOPS_USERINFO_URL=https://autogen-v2-api.nodeops.network/v1/users/me -
Create— if
.env.localdoes not already exist, copy.env.localto.env.exampleand remind the user to fill in.env.localandNEXT_PUBLIC_NODEOPS_CLIENT_IDwith their credentials from the NodeOps developer portal. IfNODEOPS_CLIENT_SECRETalready exists, append the missing.env.localvars only — do NOT overwrite existing values.NODEOPS_ -
Check— read
.gitignore(if it exists). If.gitignoreis NOT listed, add it to prevent leaking secrets. Also ensure.env.localis listed. If no.envexists, create one with at least:.gitignore.env .env.local -
Show a summary — print a clear summary:
- Files created/modified (list each one)
- Files skipped (if any were already present)
- Remind user to fill in the 2 required env vars: and
NEXT_PUBLIC_NODEOPS_CLIENT_IDNODEOPS_CLIENT_SECRET - Show how to use the hooks in any page:
tsx
import { useAuth, useUser } from '@nodeops-createos/integration-oauth'; const { isAuthenticated, login, logout, loading, authError } = useAuth(); const { user } = useUser();
-
检测项目配置 —— 读取并检查锁文件:
package.json- 包管理器:如果存在→ pnpm,如果存在
pnpm-lock.yaml→ yarn,否则 → npmyarn.lock - TypeScript:如果存在使用
tsconfig.json/.ts扩展名,否则使用.tsx/.js.jsx - 确认目录存在(App Router)。如果仅存在
app/目录,停止操作。pages/ - 确认依赖项中包含,否则停止操作。
next
- 包管理器:如果存在
-
安装依赖包 —— 运行对应的安装命令:
- npm:
npm install @nodeops-createos/integration-oauth - pnpm:
pnpm add @nodeops-createos/integration-oauth - yarn:
yarn add @nodeops-createos/integration-oauth - 如果安装失败:检查用户网络访问是否正常、registry是否可访问。如果持续失败建议用户手动运行命令。
- npm:
-
创建catch-all API路由 —— 创建(或
app/api/auth/[...nodeops]/route.ts),按需创建目录:.jstsexport { GET, POST } from '@nodeops-createos/integration-oauth/server'; -
用AuthProvider包裹布局 —— 读取根布局文件,可能为、
app/layout.tsx、app/layout.jsx或app/layout.js,找到存在的文件:app/layout.ts- 在文件顶部添加导入:
tsx
import { AuthProvider } from '@nodeops-createos/integration-oauth'; - 找到标签内的
<body>,用{children}包裹:<AuthProvider>tsx<AuthProvider>{children}</AuthProvider> - 不要在布局文件中添加"use client"。内部已经标记了
AuthProvider——从服务端组件布局中导入也可以正常运行。"use client" - 如果布局已经有其他provider(例如ThemeProvider、QueryClientProvider),将和它们并排嵌套即可,不要删除或替换已有provider。
<AuthProvider> - 如果没有直接放在
{children}内(例如放在包装div或fragment中),在<body>出现的位置包裹即可。{children} - 如果不存在布局文件,停止操作并告知用户先创建根布局。
- 在文件顶部添加导入:
-
创建回调页面 —— 询问用户:"用户登录后应该重定向到哪里?(默认:/dashboard)"。将用户的回答作为的值,然后创建
redirectTo(或app/callback/page.tsx):.jsxtsx"use client"; import { useCallbackHandler } from "@nodeops-createos/integration-oauth"; export default function Callback() { const { loading, error } = useCallbackHandler({ redirectTo: "/dashboard" }); if (loading) return ( <div style={{ display: "flex", justifyContent: "center", alignItems: "center", height: "100vh" }}> <p>Signing in...</p> </div> ); if (error) return <p>Login failed: {error}</p>; return null; } -
创建—— 在项目根目录创建该文件:
.env.example# ── Client-side (exposed to browser via NEXT_PUBLIC_ prefix) ────────────────── NEXT_PUBLIC_NODEOPS_AUTH_URL=https://id.nodeops.network/oauth2/auth NEXT_PUBLIC_NODEOPS_CLIENT_ID=your_client_id_here NEXT_PUBLIC_NODEOPS_REDIRECT_URI=http://localhost:3000/callback NEXT_PUBLIC_NODEOPS_SCOPES=offline_access offline openid # ── Server-side only (never sent to browser) ────────────────────────────────── NODEOPS_CLIENT_SECRET=your_client_secret_here NODEOPS_TOKEN_URL=https://id.nodeops.network/oauth2/token NODEOPS_USERINFO_URL=https://autogen-v2-api.nodeops.network/v1/users/me -
创建—— 如果
.env.local不存在,将.env.local复制为.env.example,并提醒用户将从NodeOps开发者门户获取的凭证填入.env.local和NEXT_PUBLIC_NODEOPS_CLIENT_ID。如果NODEOPS_CLIENT_SECRET已存在,仅追加缺失的.env.local前缀变量——不要覆盖已有值。NODEOPS_ -
检查—— 读取
.gitignore(如果存在)。如果.gitignore没有被列入,添加它以防止泄露密钥,同时确保.env.local也被列入。如果不存在.env,创建一个至少包含以下内容的文件:.gitignore.env .env.local -
展示总结 —— 输出清晰的总结:
- 已创建/修改的文件(逐个列出)
- 已跳过的文件(如果有已存在的文件)
- 提醒用户填写两个必填环境变量:和
NEXT_PUBLIC_NODEOPS_CLIENT_IDNODEOPS_CLIENT_SECRET - 展示如何在任意页面使用hooks:
tsx
import { useAuth, useUser } from '@nodeops-createos/integration-oauth'; const { isAuthenticated, login, logout, loading, authError } = useAuth(); const { user } = useUser();