mcpField
W
wire-auth

wire-auth

github.com/tushaarmehtaa开发1272 次安装2 周前更新
代码仓库

关于 wire-auth

wire-auth 是面向应用开发的认证接入 Skill,会先识别现有认证、数据库和前端框架,再补齐用户同步、访问控制与会话流程。它涵盖数据库级 RLS 和并发登录等安全细节。

主要功能

  1. 01识别认证、数据库与框架
  2. 02创建或调整用户表结构
  3. 03配置 RLS 或查询用户隔离
  4. 04接入认证提供方与会话钩子
  5. 05检查服务端路由与密钥安全
  6. 06验证注册和登录流程

适用场景

  1. 01为现有应用补充认证流程
  2. 02为 Supabase 用户数据配置 RLS
  3. 03检查不同数据库的用户隔离方式

安装

复制下面的命令,在终端中运行。

$npx skills add https://github.com/tushaarmehtaa/tushar-skills --skill wire-auth

安装后在 Claude Code 中输入/wire-auth确认已加载。

包含的文件

除 SKILL.md 外,安装时一起下载的参考资料和脚本。

references/
clerk.md
nextauth.md
supabase-auth.md

详细介绍

端到端设置身份验证——包括提供商、数据库同步、行级安全、前端钩子和会话管理。这里会处理 RLS 和竞态条件,而不是把它们留作练习。

阶段 1:检测技术栈

在编写任何内容之前,先了解现有内容。

1.1 身份验证提供商

检查是否已有身份验证:

  • @clerk/nextjs 在 package.json 中 → Clerk
  • next-auth 在 package.json 中 → NextAuth.js
  • @supabase/auth-helpers-nextjs 或 @supabase/ssr → Supabase Auth
  • firebase/auth → Firebase Auth
  • 都没有 → 询问用户要设置哪一种
1.2 数据库
  • @supabase/supabase-js → Supabase(Postgres)
  • @prisma/client → Prisma(检查 schema.prisma 中的 provider)
  • drizzle-orm → Drizzle
  • mongoose → MongoDB
  • 原生 pg 或 postgres → 直接连接 Postgres
1.3 前端框架
  • Next.js App Router 还是 Pages Router(检查是否有 app/ 或 pages/)
  • React SPA(Vite)
  • 其他
1.4 已完成的内容
  • 是否已有 users 表?阅读 schema。
  • 是否有与身份验证相关的 API 路由?
  • 是否有 middleware 文件?
  • 是否已有身份验证钩子或上下文提供程序?

告诉用户:

Detected: [auth provider] + [database] + [framework]
Users table: [exists / missing]
I'll wire: [list of what needs to be created]

阶段 2:数据库架构

如果没有 users 表

Supabase(SQL):

create table users (
  id uuid primary key default gen_random_uuid(),
  auth_id text unique not null,
  email text unique,
  name text,
  avatar_url text,
  created_at timestamptz default now(),
  updated_at timestamptz default now()
);

create index idx_users_auth_id on users(auth_id);
create index idx_users_email on users(email);

Prisma:

model User {
  id        String   @id @default(uuid())
  authId    String   @unique @map("auth_id")
  email     String?  @unique
  name      String?
  avatarUrl String?  @map("avatar_url")
  createdAt DateTime @default(now()) @map("created_at")
  updatedAt DateTime @updatedAt @map("updated_at")

  @@map("users")
}

Drizzle:

export const users = pgTable('users', {
  id: uuid('id').primaryKey().defaultRandom(),
  authId: text('auth_id').unique().notNull(),
  email: text('email').unique(),
  name: text('name'),
  avatarUrl: text('avatar_url'),
  createdAt: timestamp('created_at').defaultNow(),
  updatedAt: timestamp('updated_at').defaultNow(),
});
如果已有 users 表

如果缺少 auth_id 列,则添加:

alter table users add column if not exists auth_id text unique;
create index if not exists idx_users_auth_id on users(auth_id);

阶段 3:行级安全(RLS)

这是所有人都会跳过的部分。 如果没有 RLS,任何已通过身份验证的用户只要猜对 ID,就能读取或写入其他用户的数据。RLS 可让数据库强制执行访问规则。

对于 Supabase

在每个包含用户数据的表上启用 RLS:

-- Enable RLS
alter table users enable row level security;

-- Users can only read their own row
create policy "users_read_own"
  on users for select
  using (auth_id = current_setting('request.jwt.claims')::json->>'sub');

-- Users can only update their own row
create policy "users_update_own"
  on users for update
  using (auth_id = current_setting('request.jwt.claims')::json->>'sub');

-- Backend service role bypasses RLS for admin operations
create policy "service_role_all"
  on users for all
  using (current_setting('role') = 'service_role');

对于任何其他归用户所有的表(例如 posts、projects、settings),应用相同的模式:

alter table [table_name] enable row level security;

create policy "[table]_read_own"
  on [table_name] for select
  using (user_id = (
    select id from users where auth_id = current_setting('request.jwt.claims')::json->>'sub'
  ));

create policy "[table]_write_own"
  on [table_name] for insert
  with check (user_id = (
    select id from users where auth_id = current_setting('request.jwt.claims')::json->>'sub'
  ));

create policy "[table]_update_own"
  on [table_name] for update
  using (user_id = (
    select id from users where auth_id = current_setting('request.jwt.claims')::json->>'sub'
  ));

create policy "[table]_delete_own"
  on [table_name] for delete
  using (user_id = (
    select id from users where auth_id = current_setting('request.jwt.claims')::json->>'sub'
  ));

告诉用户:“已启用 RLS。即使有人绕过前端,数据库本身也会拒绝未经授权的访问。”

对于 Prisma / Drizzle(没有内置 RLS)

添加 middleware 或辅助函数,让每个查询都按当前用户进行筛选:

// lib/auth-filter.ts
export function forUser(userId: string) {
  return { where: { userId } };
}

// Usage in any route:
const posts = await prisma.post.findMany(forUser(session.user.id));

这并不是真正的 RLS,但属于等效模式。请告知用户,Prisma 不会在数据库层面强制执行此规则——这是应用层安全措施。

阶段 4:实现检测到的提供商

在编写身份验证集成代码之前,只阅读一个提供商参考文档:

  • **Clerk 配合 Next.js 和 Supabase:**阅读 references/clerk.md,了解数据库同步、React 钩子、中间件、API 保护和环境变量。
  • **NextAuth 配合 Next.js 和 Prisma:**阅读 references/nextauth.md,了解适配器同步、会话字段、React 钩子、中间件、API 保护和环境变量。
  • **Supabase Auth:**阅读 references/supabase-auth.md,了解公开用户触发器和环境变量。

不要混合实现不同提供商。根据阶段 1 检测到的架构和路由模式,调整所选参考文档中的实现。

阶段 5:跨提供商安全检查

完成所选提供商路径的实现后:

  • 在服务器端保护私有页面和 API 路由,不要只在客户端组件中保护。
  • 将提供商密钥和 Supabase service-role 密钥保存在仅供服务器使用的环境变量中。
  • 如果 .env 和 .env.local 中的任一文件可能被提交到仓库,请将它们添加到 .gitignore。
  • 保留阶段 3 中的数据库隔离规则。
  • 防止重复登录或 React Strict Mode 导致重复创建用户。
  • 在创建新记录之前,根据已验证的身份匹配并处理现有数据库用户。

阶段 6:验证

完成接线后,检查以下流程:

Flow 1: New User Signup
[ ] User signs up via auth provider
[ ] Sync endpoint creates user in database
[ ] Frontend hook reflects authenticated state
[ ] isNewUser flag is true (can show onboarding)

Flow 2: Returning User Login
[ ] User signs in
[ ] Sync endpoint finds existing user, updates fields
[ ] Frontend hook loads user data
[ ] isNewUser flag is false

Flow 3: Protected Routes
[ ] Unauthenticated user visiting /dashboard → redirected to sign-in
[ ] Authenticated user visiting /dashboard → sees content
[ ] API route without auth → returns 401

Flow 4: Data Isolation (if RLS enabled)
[ ] User A creates data → only User A can read it
[ ] User B cannot access User A's data even with a direct API call
[ ] Service role (backend) can access all data for admin operations

Flow 5: Edge Cases
[ ] User signs up with email, then signs in with OAuth (same email) → accounts linked
[ ] Token expires → user re-authenticates without data loss
[ ] Multiple tabs open → auth state syncs across tabs

告诉用户哪些流程已接通,哪些需要手动测试。

评论

支持 Markdown