TL;DR:在 clerk.com 注册账号,创建应用,安装 @clerk/nextjs(或对应框架的包),用 <ClerkProvider> 包裹应用,再放入 <SignIn /> 和 <UserButton />。免费套餐:10,000 月活用户。
放入 <SignIn /> 即可获得一个可用的认证界面。Clerk 负责处理密码、OAuth、MFA、会话、组织——你无需编写任何相关代码。免费套餐支持每月 10,000 名活跃用户。
Clerk 的最佳场景:快速迭代的 SaaS 初创团队,想要做好认证但不想在上面花精力。
前往 dashboard.clerk.com ↗ 注册。免费套餐:每月 10,000 活跃用户,无需绑定信用卡。
创建一个应用,选择要开启的登录方式:
进入 Dashboard → API Keys,复制以下两个值:
NEXT_PUBLIC_CLERK_PUBLISHABLE_KEY=pk_test_xxxxx
CLERK_SECRET_KEY=sk_test_xxxxx
Publishable Key 可以安全地暴露给浏览器;Secret Key 仅限后端使用。
Next.js App Router(最常见):
npm install @clerk/nextjs
在项目根目录的 middleware.ts 中:
import { clerkMiddleware } from '@clerk/nextjs/server';
export default clerkMiddleware();
export const config = {
matcher: ['/((?!_next|.*\\..*).*)', '/api/(.*)'],
};
在 app/layout.tsx 中:
import { ClerkProvider } from '@clerk/nextjs';
export default function RootLayout({ children }) {
return (
<ClerkProvider>
<html><body>{children}</body></html>
</ClerkProvider>
);
}
完成。认证功能已贯通整个应用。
以下框架同样遵循相同模式(Provider 组件 + middleware/服务端辅助函数):
Clerk 提供开箱即用的预置组件。以 Next.js 为例:
// app/sign-in/[[...sign-in]]/page.tsx
import { SignIn } from '@clerk/nextjs';
export default function Page() {
return <SignIn />;
}
这就是完整的登录页面。界面精美,并自动包含你在第 1 步开启的所有登录方式。<SignUp />、<UserButton />(带账号管理的头像下拉菜单)和 <OrganizationSwitcher /> 的用法与此相同。
// app/dashboard/page.tsx
import { auth } from '@clerk/nextjs/server';
import { redirect } from 'next/navigation';
export default async function Dashboard() {
const { userId } = await auth();
if (!userId) redirect('/sign-in');
return <div>Welcome to your dashboard</div>;
}
也可以在 middleware 中保护整组路由——匹配规则详见 clerkMiddleware 文档 ↗。
// app/api/me/route.ts
import { auth, currentUser } from '@clerk/nextjs/server';
export async function GET() {
const { userId } = await auth();
if (!userId) return new Response('Unauthorized', { status: 401 });
const user = await currentUser();
return Response.json({
email: user.emailAddresses[0].emailAddress,
name: user.firstName,
});
}
对于非 Next.js 框架:使用官方 Backend SDK 中的 JWT 验证 ↗。
Clerk 组件的默认样式简洁大方,但偏向通用风格。若要与你的品牌一致:
<ClerkProvider appearance={{
baseTheme: undefined,
variables: {
colorPrimary: '#6366f1',
colorBackground: '#ffffff',
borderRadius: '8px',
fontFamily: '"DM Sans", system-ui, sans-serif',
},
}}>
...
</ClerkProvider>
若需更深度定制(使用自己的组件),可采用 Clerk 的 Elements 原语 ↗——这是一套无样式的 headless 组件,你可以用自己的设计系统来包裹它。
如果你的产品面向 B2B(每个用户属于一个或多个公司),可在 Dashboard 中启用组织功能:
Configure → Organizations → Enable。然后在界面中添加 <OrganizationSwitcher />——它为用户提供一个下拉菜单,方便在所属组织之间切换。
在服务端,当前组织的上下文可通过 auth() 获取:
const { userId, orgId, orgRole } = await auth();
内置角色:admin、basic_member。可在 Dashboard 中添加自定义权限。组织文档 ↗。
Clerk 存储用户记录,你的数据库存储应用数据。要将两者关联,可监听 Clerk 的 webhook 事件:
Clerk Dashboard → Webhooks → New endpoint。选择要监听的事件(user.created、user.updated、user.deleted),获取签名密钥。
// app/api/webhooks/clerk/route.ts
import { Webhook } from 'svix';
export async function POST(req) {
const payload = await req.text();
const headers = Object.fromEntries(req.headers);
const wh = new Webhook(process.env.CLERK_WEBHOOK_SECRET);
const event = wh.verify(payload, headers);
if (event.type === 'user.created') {
await db.users.insert({
clerk_id: event.data.id,
email: event.data.email_addresses[0].email_address,
});
}
return new Response('ok');
}
签名验证方式与 Stripe webhooks 相同。Clerk webhooks 文档 ↗。
如果你已有用户表并希望导入:请参考 迁移指南 ↗。批量导入 API 支持常见格式的哈希密码(bcrypt、argon2、PBKDF2)。
如果你担心被供应商锁定:Clerk 支持随时导出全部用户和会话数据。迁移出去会有些麻烦,但完全可行。
auth.yourdomain.com,而非默认的 your-app.clerk.accounts.dev。免费,仅需一条 DNS 记录。