集成能力
认证
Bunship 支持 Better Auth 与 Clerk 两种认证方案。
Bunship 支持两种认证提供方:
- Better Auth(默认,完整的认证 + MFA + Passkey + API Key)
- Clerk(托管认证 UI + Webhook 同步用户)
通过设置 NEXT_PUBLIC_AUTH_PROVIDER 选择提供方。未设置时默认 better-auth。
配置
请按照所选提供方的步骤完成。
1. 选择提供方(默认:Better Auth)
# Better Auth(默认)
NEXT_PUBLIC_AUTH_PROVIDER=better-auth
# Clerk
NEXT_PUBLIC_AUTH_PROVIDER=clerk2. Better Auth 配置
生成 Better Auth 密钥
BETTER_AUTH_SECRET 用于会话与令牌签名。
openssl rand -base64 32写入 .env:
BETTER_AUTH_SECRET="YOUR-BETTER-AUTH-SECRET"
BETTER_AUTH_URL="http://localhost:3001"配置 GitHub OAuth
创建 GitHub OAuth App 并设置回调地址:
- 本地:
http://localhost:3001/api/v1/auth/callback/github - 线上:
https://YOUR_DOMAIN/api/v1/auth/callback/github
写入 .env:
OAUTH_GITHUB_CLIENT_ID="YOUR-GITHUB-CLIENT-ID"
OAUTH_GITHUB_CLIENT_SECRET="YOUR-GITHUB-CLIENT-SECRET"开发和生产环境请使用不同的 OAuth 应用。
配置 Google OAuth
创建 Google OAuth 客户端并设置回调地址:
- 本地:
http://localhost:3001/api/v1/auth/callback/google - 线上:
https://YOUR_DOMAIN/api/v1/auth/callback/google
写入 .env:
OAUTH_GOOGLE_CLIENT_ID="YOUR-GOOGLE-CLIENT-ID"
OAUTH_GOOGLE_CLIENT_SECRET="YOUR-GOOGLE-CLIENT-SECRET"
NEXT_PUBLIC_OAUTH_GOOGLE_CLIENT_ID="YOUR-GOOGLE-CLIENT-ID"启用邮箱密码登录
邮箱密码登录依赖邮件服务,请先完成邮件配置。
3. Clerk 配置
- 创建 Clerk 应用。
- 添加以下环境变量:
NEXT_PUBLIC_CLERK_PUBLISHABLE_KEY="YOUR-CLERK-PUBLISHABLE-KEY"
CLERK_SECRET_KEY="YOUR-CLERK-SECRET-KEY"
CLERK_WEBHOOK_SECRET="YOUR-CLERK-WEBHOOK-SECRET"- 配置 Clerk Webhook 同步用户到 Bunship 数据库:
- Endpoint:
https://YOUR_DOMAIN/api/v1/webhook/clerk - 事件:
user.created、user.updated、user.deleted
核心能力
- 邮箱认证与验证流程
- Google / GitHub 社交登录
- 账号联动与合并
- 邮箱/OAuth 邀请归因
- 新用户自动初始化钱包
仅 Better Auth 支持:
- MFA 与 Passkey
- API Key 管理
客户端用法
获取会话
'use client';
import { authClient } from '@/lib/auth-client';
export function ProfileButton() {
const { data: session, isPending } = authClient.useSession();
if (isPending) return <div>Loading...</div>;
if (!session?.user) return <button>Sign in</button>;
return <button>{session.user.name}</button>;
}认证操作
authClient.signIn.* 仅适用于 Better Auth。Clerk 模式请使用 SignIn / SignUp 等 Clerk 组件。
import { authClient } from '@/lib/auth-client';
await authClient.signIn.email({
email: 'user@example.com',
password: 'password123',
});
await authClient.signIn.social({
provider: 'google',
callbackURL: '/',
});
await authClient.signOut();服务端用法
路由保护
import { getSession } from '@/lib/session';
import { redirect } from 'next/navigation';
export default async function ProtectedPage() {
const session = await getSession();
if (!session?.user) {
redirect('/signin');
}
return <div>Protected content</div>;
}管理员权限
import { getSession } from '@/lib/session';
import { redirect } from 'next/navigation';
export default async function AdminPage() {
const session = await getSession();
if (!session?.user || session.user.role !== 'admin') {
redirect('/signin');
}
return <div>Admin content</div>;
}最佳实践
- OAuth 应用与密钥按环境隔离。
- 回调地址需与部署域名严格一致。
- 敏感路由必须服务端校验角色。
- 认证失败优先检查回调地址、Cookie 策略与环境变量一致性。
- Clerk 需确保 Webhook 事件稳定送达且幂等。