nodeops-auth

Compare original and translation side by side

🇺🇸

Original

English
🇨🇳

Translation

Chinese

NodeOps 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
    app/
    directory exists. If only
    pages/
    exists, stop and tell the user: "This skill only supports Next.js App Router. Your project uses Pages Router."
  • Next.js required: Check
    package.json
    for
    next
    in dependencies. If missing, stop and tell the user this is a Next.js-only package.
开始前请确认项目兼容性:
  • 必须使用App Router:检查是否存在
    app/
    目录。如果仅存在
    pages/
    目录,停止操作并告知用户:"本技能仅支持Next.js App Router,你的项目使用的是Pages Router。"
  • 必须是Next.js项目:检查
    package.json
    的依赖项中是否包含
    next
    。如果缺失,停止操作并告知用户这是仅适用于Next.js的包。

Idempotency

幂等性处理

Before each step, check if the work is already done. Skip steps that are already complete:
  • If
    @nodeops-createos/integration-oauth
    is already in
    package.json
    dependencies, skip install.
  • If
    app/api/auth/[...nodeops]/route.ts
    (or
    .js
    ) already exists, skip route creation.
  • If
    AuthProvider
    from
    @nodeops-createos/integration-oauth
    is already imported in the layout, skip wrapping.
  • If
    app/callback/page.tsx
    (or
    .jsx
    ) already exists, skip callback page creation.
  • If
    .env.example
    already exists and contains
    NODEOPS_
    , skip env file creation.
每步操作前先检查是否已经完成,跳过已完成的步骤:
  • 如果
    @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

操作步骤

  1. Detect project setup — read
    package.json
    and check for lock files:
    • Package manager: if
      pnpm-lock.yaml
      exists → pnpm, if
      yarn.lock
      exists → yarn, else → npm
    • TypeScript: if
      tsconfig.json
      exists use
      .ts
      /
      .tsx
      extensions, else
      .js
      /
      .jsx
    • Confirm
      app/
      directory exists (App Router). If only
      pages/
      exists, stop.
    • Confirm
      next
      is in dependencies. If not, stop.
  2. 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.
  3. Create the catch-all API route — create
    app/api/auth/[...nodeops]/route.ts
    (or
    .js
    ), creating directories as needed:
    ts
    export { GET, POST } from '@nodeops-createos/integration-oauth/server';
  4. Wrap layout with AuthProvider — read the root layout file. It could be
    app/layout.tsx
    ,
    app/layout.jsx
    ,
    app/layout.js
    , or
    app/layout.ts
    . Find whichever exists.
    • Add the import at the top of the file:
      tsx
      import { AuthProvider } from '@nodeops-createos/integration-oauth';
    • Find
      {children}
      inside the
      <body>
      tag. Wrap it with
      <AuthProvider>
      :
      tsx
      <AuthProvider>{children}</AuthProvider>
    • Do NOT add "use client" to the layout.
      AuthProvider
      is already marked
      "use client"
      internally — it works fine when imported from a Server Component layout.
    • If the layout already has other providers (e.g., ThemeProvider, QueryClientProvider), nest
      <AuthProvider>
      alongside them. Do NOT remove or replace existing providers.
    • If
      {children}
      is not directly inside
      <body>
      (e.g., it's inside a wrapper div or fragment), wrap wherever
      {children}
      appears.
    • If no layout file exists, stop and tell the user to create a root layout first.
  5. Create the callback page — ask the user: "Where should users be redirected after login? (default: /dashboard)". Use their answer as the
    redirectTo
    value. Then create
    app/callback/page.tsx
    (or
    .jsx
    ):
    tsx
    "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;
    }
  6. Create
    .env.example
    — create this file at the project root:
    # ── 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
  7. Create
    .env.local
    — if
    .env.local
    does not already exist, copy
    .env.example
    to
    .env.local
    and remind the user to fill in
    NEXT_PUBLIC_NODEOPS_CLIENT_ID
    and
    NODEOPS_CLIENT_SECRET
    with their credentials from the NodeOps developer portal. If
    .env.local
    already exists, append the missing
    NODEOPS_
    vars only — do NOT overwrite existing values.
  8. Check
    .gitignore
    — read
    .gitignore
    (if it exists). If
    .env.local
    is NOT listed, add it to prevent leaking secrets. Also ensure
    .env
    is listed. If no
    .gitignore
    exists, create one with at least:
    .env
    .env.local
  9. 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:
      NEXT_PUBLIC_NODEOPS_CLIENT_ID
      and
      NODEOPS_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();
  1. 检测项目配置 —— 读取
    package.json
    并检查锁文件:
    • 包管理器:如果存在
      pnpm-lock.yaml
      → pnpm,如果存在
      yarn.lock
      → yarn,否则 → npm
    • TypeScript:如果存在
      tsconfig.json
      使用
      .ts
      /
      .tsx
      扩展名,否则使用
      .js
      /
      .jsx
    • 确认
      app/
      目录存在(App Router)。如果仅存在
      pages/
      目录,停止操作。
    • 确认依赖项中包含
      next
      ,否则停止操作。
  2. 安装依赖包 —— 运行对应的安装命令:
    • npm:
      npm install @nodeops-createos/integration-oauth
    • pnpm:
      pnpm add @nodeops-createos/integration-oauth
    • yarn:
      yarn add @nodeops-createos/integration-oauth
    • 如果安装失败:检查用户网络访问是否正常、registry是否可访问。如果持续失败建议用户手动运行命令。
  3. 创建catch-all API路由 —— 创建
    app/api/auth/[...nodeops]/route.ts
    (或
    .js
    ),按需创建目录:
    ts
    export { GET, POST } from '@nodeops-createos/integration-oauth/server';
  4. 用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),将
      <AuthProvider>
      和它们并排嵌套即可,不要删除或替换已有provider。
    • 如果
      {children}
      没有直接放在
      <body>
      (例如放在包装div或fragment中),在
      {children}
      出现的位置包裹即可。
    • 如果不存在布局文件,停止操作并告知用户先创建根布局。
  5. 创建回调页面 —— 询问用户:"用户登录后应该重定向到哪里?(默认:/dashboard)"。将用户的回答作为
    redirectTo
    的值,然后创建
    app/callback/page.tsx
    (或
    .jsx
    ):
    tsx
    "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;
    }
  6. 创建
    .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
  7. 创建
    .env.local
    —— 如果
    .env.local
    不存在,将
    .env.example
    复制为
    .env.local
    ,并提醒用户将从NodeOps开发者门户获取的凭证填入
    NEXT_PUBLIC_NODEOPS_CLIENT_ID
    NODEOPS_CLIENT_SECRET
    。如果
    .env.local
    已存在,仅追加缺失的
    NODEOPS_
    前缀变量——不要覆盖已有值。
  8. 检查
    .gitignore
    —— 读取
    .gitignore
    (如果存在)。如果
    .env.local
    没有被列入,添加它以防止泄露密钥,同时确保
    .env
    也被列入。如果不存在
    .gitignore
    ,创建一个至少包含以下内容的文件:
    .env
    .env.local
  9. 展示总结 —— 输出清晰的总结:
    • 已创建/修改的文件(逐个列出)
    • 已跳过的文件(如果有已存在的文件)
    • 提醒用户填写两个必填环境变量:
      NEXT_PUBLIC_NODEOPS_CLIENT_ID
      NODEOPS_CLIENT_SECRET
    • 展示如何在任意页面使用hooks:
      tsx
      import { useAuth, useUser } from '@nodeops-createos/integration-oauth';
      
      const { isAuthenticated, login, logout, loading, authError } = useAuth();
      const { user } = useUser();