关于 wire-auth
wire-auth 是面向应用开发的认证接入 Skill,会先识别现有认证、数据库和前端框架,再补齐用户同步、访问控制与会话流程。它涵盖数据库级 RLS 和并发登录等安全细节。
主要功能
- 01识别认证、数据库与框架
- 02创建或调整用户表结构
- 03配置 RLS 或查询用户隔离
- 04接入认证提供方与会话钩子
- 05检查服务端路由与密钥安全
- 06验证注册和登录流程
适用场景
- 01为现有应用补充认证流程
- 02为 Supabase 用户数据配置 RLS
- 03检查不同数据库的用户隔离方式
安装
复制下面的命令,在终端中运行。
$
npx skills add https:/ / github.com/ tushaarmehtaa/ tushar-skills --skill wire-auth安装后在 Claude Code 中输入/wire-auth确认已加载。
包含的文件
除 SKILL.md 外,安装时一起下载的参考资料和脚本。
references/clerk.mdnextauth.mdsupabase-auth.md详细介绍
端到端设置身份验证——包括提供商、数据库同步、行级安全、前端钩子和会话管理。这里会处理 RLS 和竞态条件,而不是把它们留作练习。
阶段 1:检测技术栈
在编写任何内容之前,先了解现有内容。
1.1 身份验证提供商
检查是否已有身份验证:
@clerk/nextjs在 package.json 中 → Clerknext-auth在 package.json 中 → NextAuth.js@supabase/auth-helpers-nextjs或@supabase/ssr→ Supabase Authfirebase/auth→ Firebase Auth- 都没有 → 询问用户要设置哪一种
1.2 数据库
@supabase/supabase-js→ Supabase(Postgres)@prisma/client→ Prisma(检查 schema.prisma 中的 provider)drizzle-orm→ Drizzlemongoose→ 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