better-auth

Compare original and translation side by side

🇺🇸

Original

English
🇨🇳

Translation

Chinese

Better Auth Integration Guide

Better Auth集成指南

Overview

概述

Better Auth is a comprehensive authentication framework for TypeScript that provides type-safe authentication with support for multiple providers, 2FA, SSO, organizations, and more. This skill covers complete integration patterns for NestJS backend with Drizzle ORM and PostgreSQL, plus Next.js App Router frontend integration.
Better Auth是一款面向TypeScript的全功能认证框架,提供类型安全的认证能力,支持多登录提供商、2FA、SSO、组织管理等功能。本指南涵盖NestJS后端结合Drizzle ORM与PostgreSQL的完整集成方案,以及Next.js App Router前端的集成方法。

When to Use

适用场景

  • Setting up Better Auth with NestJS backend
  • Integrating Next.js App Router frontend with Better Auth
  • Configuring Drizzle ORM schema with PostgreSQL for authentication
  • Implementing social login (GitHub, Google, Facebook, Microsoft, etc.)
  • Adding Multi-Factor Authentication (MFA/2FA) with TOTP
  • Implementing passkey (WebAuthn) passwordless authentication
  • Managing trusted devices for streamlined authentication
  • Using backup codes for 2FA account recovery
  • Adding authentication plugins (2FA, Organization, SSO, Magic Link, Passkey)
  • Email/password authentication with secure session management
  • Creating protected routes and authentication middleware
  • Implementing role-based access control (RBAC)
  • Building multi-tenant applications with organizations
  • 在NestJS后端中搭建Better Auth
  • 为Next.js App Router前端集成Better Auth
  • 配置基于PostgreSQL的Drizzle ORM认证schema
  • 实现社交登录(GitHub、Google、Facebook、Microsoft等)
  • 添加多因素认证(MFA/2FA)与TOTP支持
  • 实现密钥登录(WebAuthn)无密码认证
  • 管理可信设备以简化认证流程
  • 使用备份码进行2FA账号恢复
  • 添加认证插件(2FA、组织管理、SSO、魔法链接、密钥登录)
  • 带安全会话管理的邮箱/密码认证
  • 创建受保护路由与认证中间件
  • 实现基于角色的访问控制(RBAC)
  • 构建支持组织的多租户应用

Quick Start

快速开始

Installation

安装

bash
undefined
bash
undefined

Backend (NestJS)

后端(NestJS)

npm install better-auth @auth/drizzle-adapter npm install drizzle-orm pg npm install -D drizzle-kit
npm install better-auth @auth/drizzle-adapter npm install drizzle-orm pg npm install -D drizzle-kit

Frontend (Next.js)

前端(Next.js)

npm install better-auth
undefined
npm install better-auth
undefined

Basic Setup

基础配置

  1. Configure Better Auth instance (backend)
  2. Set up Drizzle schema with Better Auth tables
  3. Create auth module in NestJS
  4. Configure Next.js auth client
  5. Set up middleware for protected routes
See References/ for detailed setup instructions.
  1. 配置Better Auth实例(后端)
  2. 使用Better Auth表设置Drizzle schema
  3. 在NestJS中创建认证模块
  4. 配置Next.js认证客户端
  5. 为受保护路由设置中间件
详细配置说明请查看References/目录。

Architecture

架构

Backend (NestJS)

后端(NestJS)

src/
├── auth/
│   ├── auth.module.ts           # Auth module configuration
│   ├── auth.controller.ts       # Auth HTTP endpoints
│   ├── auth.service.ts          # Business logic
│   ├── auth.guard.ts            # Route protection
│   └── schema.ts                # Drizzle auth schema
├── database/
│   ├── database.module.ts       # Database module
│   └── database.service.ts      # Drizzle connection
└── main.ts
src/
├── auth/
│   ├── auth.module.ts           # 认证模块配置
│   ├── auth.controller.ts       # 认证HTTP端点
│   ├── auth.service.ts          # 业务逻辑
│   ├── auth.guard.ts            # 路由保护
│   └── schema.ts                # Drizzle认证schema
├── database/
│   ├── database.module.ts       # 数据库模块
│   └── database.service.ts      # Drizzle连接
└── main.ts

Frontend (Next.js)

前端(Next.js)

app/
├── (auth)/
│   ├── sign-in/
│   │   └── page.tsx            # Sign in page
│   └── sign-up/
│       └── page.tsx            # Sign up page
├── (dashboard)/
│   ├── dashboard/
│   │   └── page.tsx            # Protected page
│   └── layout.tsx              # With auth check
├── api/
│   └── auth/
│       └── [...auth]/route.ts  # Auth API route
├── layout.tsx                   # Root layout
└── middleware.ts                # Auth middleware
lib/
├── auth.ts                      # Better Auth client
└── utils.ts
app/
├── (auth)/
│   ├── sign-in/
│   │   └── page.tsx            # 登录页面
│   └── sign-up/
│       └── page.tsx            # 注册页面
├── (dashboard)/
│   ├── dashboard/
│   │   └── page.tsx            # 受保护页面
│   └── layout.tsx              # 带认证检查的布局
├── api/
│   └── auth/
│       └── [...auth]/route.ts  # 认证API路由
├── layout.tsx                   # 根布局
└── middleware.ts                # 认证中间件
lib/
├── auth.ts                      # Better Auth客户端
└── utils.ts

Instructions

操作步骤

Phase 1: Database Setup

阶段1:数据库配置

  1. Install Dependencies
    bash
    npm install drizzle-orm pg @auth/drizzle-adapter better-auth
    npm install -D drizzle-kit
  2. Configure Drizzle
    • Create
      drizzle.config.ts
    • Set up database connection
    • Define schema with Better Auth tables
  3. Generate and Run Migrations
    bash
    npx drizzle-kit generate
    npx drizzle-kit migrate
  1. 安装依赖
    bash
    npm install drizzle-orm pg @auth/drizzle-adapter better-auth
    npm install -D drizzle-kit
  2. 配置Drizzle
    • 创建
      drizzle.config.ts
    • 设置数据库连接
    • 定义包含Better Auth表的schema
  3. 生成并运行迁移
    bash
    npx drizzle-kit generate
    npx drizzle-kit migrate

Phase 2: Backend Setup (NestJS)

阶段2:后端配置(NestJS)

  1. Create Database Module
    • Set up Drizzle connection
    • Provide database service
  2. Configure Better Auth
    • Create auth instance with Drizzle adapter
    • Configure providers (GitHub, Google, etc.)
    • Set up session management
  3. Create Auth Module
    • Auth controller with endpoints
    • Auth service with business logic
    • Auth guard for protection
  1. 创建数据库模块
    • 设置Drizzle连接
    • 提供数据库服务
  2. 配置Better Auth
    • 使用Drizzle适配器创建认证实例
    • 配置登录提供商(GitHub、Google等)
    • 设置会话管理
  3. 创建认证模块
    • 带端点的认证控制器
    • 带业务逻辑的认证服务
    • 用于保护路由的认证守卫

Phase 3: Frontend Setup (Next.js)

阶段3:前端配置(Next.js)

  1. Configure Auth Client
    • Set up Better Auth client
    • Configure server actions
  2. Create Auth Pages
    • Sign in page
    • Sign up page
    • Error handling
  3. Add Middleware
    • Protect routes
    • Handle redirects
  1. 配置认证客户端
    • 设置Better Auth客户端
    • 配置服务器操作
  2. 创建认证页面
    • 登录页面
    • 注册页面
    • 错误处理
  3. 添加中间件
    • 保护路由
    • 处理重定向

Phase 4: Advanced Features

阶段4:高级功能

  1. Social Providers
    • Configure OAuth apps
    • Add provider callbacks
  2. Plugins
    • Two-Factor Authentication (2FA)
    • Organizations
    • SSO
    • Magic Links
    • Passkeys
  1. 社交登录提供商
    • 配置OAuth应用
    • 添加提供商回调
  2. 插件
    • 双因素认证(2FA)
    • 组织管理
    • SSO
    • 魔法链接
    • 密钥登录

Examples

示例

Example 1: Complete NestJS Auth Setup

示例1:完整NestJS认证配置

Input: Developer needs to set up Better Auth in a new NestJS project with PostgreSQL.
Process:
typescript
// 1. Create auth instance
export const auth = betterAuth({
  database: drizzleAdapter(db, {
    provider: "pg",
    schema: { ...schema }
  }),
  socialProviders: {
    github: {
      clientId: process.env.GITHUB_CLIENT_ID!,
      clientSecret: process.env.GITHUB_CLIENT_SECRET!,
    }
  }
});

// 2. Create auth controller
@Controller('auth')
export class AuthController {
  @All('*')
  async handleAuth(@Req() req: Request, @Res() res: Response) {
    return auth.handler(req);
  }
}
Output: Fully functional auth endpoints at
/auth/*
with GitHub OAuth support.
需求:开发者需要在新的NestJS项目中结合PostgreSQL搭建Better Auth。
实现流程
typescript
// 1. 创建认证实例
export const auth = betterAuth({
  database: drizzleAdapter(db, {
    provider: "pg",
    schema: { ...schema }
  }),
  socialProviders: {
    github: {
      clientId: process.env.GITHUB_CLIENT_ID!,
      clientSecret: process.env.GITHUB_CLIENT_SECRET!,
    }
  }
});

// 2. 创建认证控制器
@Controller('auth')
export class AuthController {
  @All('*')
  async handleAuth(@Req() req: Request, @Res() res: Response) {
    return auth.handler(req);
  }
}
结果:在
/auth/*
路径下生成带GitHub OAuth支持的完整功能认证端点。

Example 2: Next.js Middleware for Route Protection

示例2:Next.js路由保护中间件

Input: Protect dashboard routes in Next.js App Router.
Process:
typescript
// middleware.ts
import { auth } from '@/lib/auth';

export default auth((req) => {
  if (!req.auth && req.nextUrl.pathname.startsWith('/dashboard')) {
    const newUrl = new URL('/sign-in', req.nextUrl.origin);
    return Response.redirect(newUrl);
  }
});

export const config = {
  matcher: ['/dashboard/:path*', '/api/protected/:path*']
};
Output: Unauthenticated users are redirected to
/sign-in
when accessing
/dashboard/*
.
需求:在Next.js App Router中保护仪表盘路由。
实现流程
typescript
// middleware.ts
import { auth } from '@/lib/auth';

export default auth((req) => {
  if (!req.auth && req.nextUrl.pathname.startsWith('/dashboard')) {
    const newUrl = new URL('/sign-in', req.nextUrl.origin);
    return Response.redirect(newUrl);
  }
});

export const config = {
  matcher: ['/dashboard/:path*', '/api/protected/:path*']
};
结果:未认证用户访问
/dashboard/*
时会被重定向到
/sign-in
页面。

Example 3: Server Component with Session

示例3:带会话的Next.js服务器组件

Input: Display user data in a Next.js Server Component.
Process:
typescript
// app/dashboard/page.tsx
import { auth } from '@/lib/auth';
import { redirect } from 'next/navigation';

export default async function DashboardPage() {
  const session = await auth();

  if (!session) {
    redirect('/sign-in');
  }

  return (
    <div>
      <h1>Welcome, {session.user.name}</h1>
      <p>Email: {session.user.email}</p>
    </div>
  );
}
Output: Renders user information only for authenticated users, redirects others to sign-in.
需求:在Next.js服务器组件中显示用户数据。
实现流程
typescript
// app/dashboard/page.tsx
import { auth } from '@/lib/auth';
import { redirect } from 'next/navigation';

export default async function DashboardPage() {
  const session = await auth();

  if (!session) {
    redirect('/sign-in');
  }

  return (
    <div>
      <h1>欢迎,{session.user.name}</h1>
      <p>邮箱:{session.user.email}</p>
    </div>
  );
}
结果:仅为已认证用户渲染用户信息,未认证用户会被重定向到登录页面。

Example 4: Adding Two-Factor Authentication

示例4:添加双因素认证

Input: Enable 2FA for enhanced account security.
Process:
typescript
// Enable 2FA plugin
export const auth = betterAuth({
  plugins: [
    twoFactor({
      issuer: 'MyApp',
      otpOptions: {
        digits: 6,
        period: 30
      }
    })
  ]
});

// Client-side enable 2FA
const { data, error } = await authClient.twoFactor.enable({
  password: 'user-password'
});
Output: Users can enable TOTP-based 2FA and verify with authenticator apps.
需求:启用2FA以增强账号安全性。
实现流程
typescript
// 启用2FA插件
export const auth = betterAuth({
  plugins: [
    twoFactor({
      issuer: 'MyApp',
      otpOptions: {
        digits: 6,
        period: 30
      }
    })
  ]
});

// 客户端启用2FA
const { data, error } = await authClient.twoFactor.enable({
  password: 'user-password'
});
结果:用户可启用基于TOTP的2FA,并使用认证器应用进行验证。

Example 5: TOTP Verification with Trusted Device

示例5:带可信设备的TOTP验证

Input: User has enabled 2FA and wants to sign in, marking the device as trusted.
Process:
typescript
// Server-side: Configure 2FA with OTP sending
export const auth = betterAuth({
  plugins: [
    twoFactor({
      issuer: 'MyApp',
      otpOptions: {
        async sendOTP({ user, otp }, ctx) {
          // Send OTP via email, SMS, or other method
          await sendEmail({
            to: user.email,
            subject: 'Your verification code',
            body: `Code: ${otp}`
          });
        }
      }
    })
  ]
});

// Client-side: Verify TOTP and trust device
const verify2FA = async (code: string) => {
  const { data, error } = await authClient.twoFactor.verifyTotp({
    code,
    trustDevice: true  // Device trusted for 30 days
  });

  if (data) {
    // Redirect to dashboard
    router.push('/dashboard');
  }
};
Output: User is authenticated, device is trusted for 30 days (no 2FA prompt on next sign-ins).
需求:用户已启用2FA,登录时将设备标记为可信设备。
实现流程
typescript
// 服务器端:配置带OTP发送的2FA
export const auth = betterAuth({
  plugins: [
    twoFactor({
      issuer: 'MyApp',
      otpOptions: {
        async sendOTP({ user, otp }, ctx) {
          // 通过邮箱、短信或其他方式发送OTP
          await sendEmail({
            to: user.email,
            subject: '您的验证码',
            body: `验证码:${otp}`
          });
        }
      }
    })
  ]
});

// 客户端:验证TOTP并信任设备
const verify2FA = async (code: string) => {
  const { data, error } = await authClient.twoFactor.verifyTotp({
    code,
    trustDevice: true  // 设备将被信任30天
  });

  if (data) {
    // 重定向到仪表盘
    router.push('/dashboard');
  }
};
结果:用户完成认证,设备被信任30天(下次登录无需2FA验证)。

Example 6: Passkey Authentication Setup

示例6:密钥登录(Passkey)配置

Input: Enable passkey (WebAuthn) authentication for passwordless login.
Process:
typescript
// Server-side: Configure passkey plugin
import { passkey } from '@better-auth/passkey';

export const auth = betterAuth({
  plugins: [
    passkey({
      rpID: 'example.com',      // Relying Party ID (your domain)
      rpName: 'My App',         // Display name
      advanced: {
        webAuthnChallengeCookie: 'my-app-passkey'
      }
    })
  ]
});

// Client-side: Register passkey
const registerPasskey = async () => {
  const { data, error } = await authClient.passkey.register({
    name: 'My Device'
  });

  if (data) {
    console.log('Passkey registered successfully');
  }
};

// Client-side: Sign in with passkey
const signInWithPasskey = async () => {
  await authClient.signIn.passkey({
    autoFill: true,  // Enable conditional UI
    fetchOptions: {
      onSuccess() {
        router.push('/dashboard');
      }
    }
  });
};
Output: Users can register and authenticate with passkeys (biometric, PIN, or security key).
需求:启用密钥登录(WebAuthn)实现无密码登录。
实现流程
typescript
// 服务器端:配置密钥登录插件
import { passkey } from '@better-auth/passkey';

export const auth = betterAuth({
  plugins: [
    passkey({
      rpID: 'example.com',      // 依赖方ID(你的域名)
      rpName: 'My App',         // 显示名称
      advanced: {
        webAuthnChallengeCookie: 'my-app-passkey'
      }
    })
  ]
});

// 客户端:注册密钥
const registerPasskey = async () => {
  const { data, error } = await authClient.passkey.register({
    name: 'My Device'
  });

  if (data) {
    console.log('密钥注册成功');
  }
};

// 客户端:使用密钥登录
const signInWithPasskey = async () => {
  await authClient.signIn.passkey({
    autoFill: true,  // 启用条件UI
    fetchOptions: {
      onSuccess() {
        router.push('/dashboard');
      }
    }
  });
};
结果:用户可注册并使用密钥(生物识别、PIN或安全密钥)进行认证。

Example 7: Passkey Conditional UI (Autofill)

示例7:密钥登录条件UI(自动填充)

Input: Implement passkey autofill in sign-in form for seamless authentication.
Process:
tsx
// Component with conditional UI support
'use client';

import { useEffect } from 'react';
import { authClient } from '@/lib/auth/client';

export default function SignInPage() {
  useEffect(() => {
    // Check for conditional mediation support
    if (!PublicKeyCredential.isConditionalMediationAvailable ||
        !PublicKeyCredential.isConditionalMediationAvailable()) {
      return;
    }

    // Enable passkey autofill
    void authClient.signIn.passkey({ autoFill: true });
  }, []);

  return (
    <form>
      <label htmlFor="email">Email:</label>
      <input
        type="email"
        name="email"
        autoComplete="username webauthn"
      />
      <label htmlFor="password">Password:</label>
      <input
        type="password"
        name="password"
        autoComplete="current-password webauthn"
      />
      <button type="submit">Sign In</button>
    </form>
  );
}
Output: Browser automatically suggests passkeys when user focuses on input fields.
需求:在登录表单中实现密钥自动填充以简化认证流程。
实现流程
tsx
// 支持条件UI的组件
'use client';

import { useEffect } from 'react';
import { authClient } from '@/lib/auth/client';

export default function SignInPage() {
  useEffect(() => {
    // 检查是否支持条件中介
    if (!PublicKeyCredential.isConditionalMediationAvailable ||
        !PublicKeyCredential.isConditionalMediationAvailable()) {
      return;
    }

    // 启用密钥自动填充
    void authClient.signIn.passkey({ autoFill: true });
  }, []);

  return (
    <form>
      <label htmlFor="email">邮箱:</label>
      <input
        type="email"
        name="email"
        autoComplete="username webauthn"
      />
      <label htmlFor="password">密码:</label>
      <input
        type="password"
        name="password"
        autoComplete="current-password webauthn"
      />
      <button type="submit">登录</button>
    </form>
  );
}
结果:当用户聚焦输入框时,浏览器会自动提示可用的密钥。

Example 8: Backup Codes for 2FA Recovery

示例8:2FA恢复用备份码

Input: User needs backup codes to recover account if authenticator app is lost.
Process:
typescript
// Enable 2FA - backup codes are generated automatically
const enable2FA = async (password: string) => {
  const { data, error } = await authClient.twoFactor.enable({
    password
  });

  if (data) {
    // IMPORTANT: Display backup codes to user immediately
    console.log('Backup codes (save these securely):');
    data.backupCodes.forEach((code: string) => {
      console.log(code);
    });

    // Show TOTP URI as QR code
    const qrCodeUrl = data.totpURI;
    displayQRCode(qrCodeUrl);
  }
};

// Recover with backup code
const recoverWithBackupCode = async (code: string) => {
  const { data, error } = await authClient.twoFactor.verifyBackupCode({
    code
  });

  if (data) {
    // Allow user to disable 2FA or set up new authenticator
    router.push('/settings/2fa');
  }
};
Output: User receives single-use backup codes for account recovery.
需求:用户需要备份码,以便在丢失认证器应用时恢复账号。
实现流程
typescript
// 启用2FA - 自动生成备份码
const enable2FA = async (password: string) => {
  const { data, error } = await authClient.twoFactor.enable({
    password
  });

  if (data) {
    // 重要:立即向用户显示备份码
    console.log('备份码(请妥善保存):');
    data.backupCodes.forEach((code: string) => {
      console.log(code);
    });

    // 将TOTP URI显示为二维码
    const qrCodeUrl = data.totpURI;
    displayQRCode(qrCodeUrl);
  }
};

// 使用备份码恢复账号
const recoverWithBackupCode = async (code: string) => {
  const { data, error } = await authClient.twoFactor.verifyBackupCode({
    code
  });

  if (data) {
    // 允许用户禁用2FA或设置新的认证器
    router.push('/settings/2fa');
  }
};
结果:用户获取一次性备份码用于账号恢复。

Common Patterns

常见模式

Protected Route Pattern

受保护路由模式

typescript
// NestJS Guard
@Controller('dashboard')
@UseGuards(AuthGuard)
export class DashboardController {
  @Get()
  getDashboard(@Request() req) {
    return req.user;
  }
}
typescript
// Next.js Server Component
import { auth } from '@/lib/auth';
import { redirect } from 'next/navigation';

export default async function Dashboard() {
  const session = await auth();
  if (!session) {
    redirect('/sign-in');
  }
  return <div>Welcome {session.user.name}</div>;
}
typescript
// NestJS守卫
@Controller('dashboard')
@UseGuards(AuthGuard)
export class DashboardController {
  @Get()
  getDashboard(@Request() req) {
    return req.user;
  }
}
typescript
// Next.js服务器组件
import { auth } from '@/lib/auth';
import { redirect } from 'next/navigation';

export default async function Dashboard() {
  const session = await auth();
  if (!session) {
    redirect('/sign-in');
  }
  return <div>欢迎 {session.user.name}</div>;
}

Session Management Pattern

会话管理模式

typescript
// Get session in API route
const session = await auth.api.getSession({
  headers: await headers()
});

// Get session in Server Component
const session = await auth();

// Get session in Client Component
'use client';
import { useSession } from '@/lib/auth/client';
const { data: session } = useSession();
typescript
// 在API路由中获取会话
const session = await auth.api.getSession({
  headers: await headers()
});

// 在服务器组件中获取会话
const session = await auth();

// 在客户端组件中获取会话
'use client';
import { useSession } from '@/lib/auth/client';
const { data: session } = useSession();

Best Practices

最佳实践

  1. Environment Variables: Always use environment variables for sensitive data (secrets, database URLs, OAuth credentials)
  2. Secret Generation: Use strong, unique secrets for Better Auth. Generate with
    openssl rand -base64 32
  3. HTTPS Required: OAuth callbacks require HTTPS in production. Use
    ngrok
    or similar for local testing
  4. Session Security: Configure appropriate session expiration times based on your security requirements
  5. Database Indexing: Add indexes on frequently queried fields (email, userId) for performance
  6. Error Handling: Implement proper error handling for auth failures without revealing sensitive information
  7. Rate Limiting: Add rate limiting to auth endpoints to prevent brute force attacks
  8. CSRF Protection: Better Auth includes CSRF protection. Always use the provided methods for state changes
  9. Type Safety: Leverage TypeScript types from Better Auth for full type safety across frontend and backend
  10. Testing: Test auth flows thoroughly including success cases, error cases, and edge conditions
  1. 环境变量:始终使用环境变量存储敏感数据(密钥、数据库URL、OAuth凭证)
  2. 密钥生成:为Better Auth使用强唯一密钥,可通过
    openssl rand -base64 32
    生成
  3. HTTPS要求:生产环境中OAuth回调需要HTTPS,本地测试可使用
    ngrok
    等工具
  4. 会话安全:根据安全需求配置合适的会话过期时间
  5. 数据库索引:为频繁查询的字段(邮箱、userId)添加索引以提升性能
  6. 错误处理:为认证失败实现适当的错误处理,避免泄露敏感信息
  7. 速率限制:为认证端点添加速率限制以防止暴力破解攻击
  8. CSRF保护:Better Auth内置CSRF保护,状态变更时请始终使用提供的方法
  9. 类型安全:利用Better Auth提供的TypeScript类型,在前后端实现完整的类型安全
  10. 测试:全面测试认证流程,包括成功场景、错误场景和边缘情况

Constraints and Warnings

约束与警告

Security Notes

安全注意事项

  • Never commit secrets: Add
    .env
    to
    .gitignore
    and never commit OAuth secrets or database credentials
  • Validate redirect URLs: Always validate OAuth redirect URLs to prevent open redirects
  • Hash passwords: Better Auth handles password hashing automatically. Never implement your own
  • Session storage: For production, use Redis or another scalable session store
  • HTTPS Only: Always use HTTPS for authentication in production
  • OAuth Secrets: Keep OAuth client secrets secure. Rotate them periodically
  • Email Verification: Always implement email verification for password-based auth
  • 切勿提交密钥:将
    .env
    添加到
    .gitignore
    中,绝不要提交OAuth密钥或数据库凭证
  • 验证重定向URL:始终验证OAuth重定向URL以防止开放重定向攻击
  • 密码哈希:Better Auth会自动处理密码哈希,切勿自行实现
  • 会话存储:生产环境中请使用Redis或其他可扩展的会话存储
  • 仅使用HTTPS:生产环境中认证必须使用HTTPS
  • OAuth密钥安全:妥善保管OAuth客户端密钥,并定期轮换
  • 邮箱验证:基于密码的认证务必实现邮箱验证

Known Limitations

已知限制

  • Better Auth requires Node.js 18+ for Next.js App Router support
  • Some OAuth providers require specific redirect URL formats
  • Passkeys require HTTPS and compatible browsers
  • Organization features require additional database tables
  • Better Auth需要Node.js 18+以支持Next.js App Router
  • 部分OAuth提供商要求特定的重定向URL格式
  • 密钥登录需要HTTPS和兼容的浏览器
  • 组织功能需要额外的数据库表

Version Requirements

版本要求

Backend Dependencies

后端依赖

json
{
  "dependencies": {
    "better-auth": "^1.2.0",
    "@auth/drizzle-adapter": "^1.0.0",
    "drizzle-orm": "^0.35.0",
    "pg": "^8.12.0",
    "@nestjs/common": "^10.0.0",
    "@nestjs/core": "^10.0.0",
    "@nestjs/config": "^3.0.0"
  },
  "devDependencies": {
    "drizzle-kit": "^0.24.0",
    "@types/pg": "^8.11.0"
  }
}
json
{
  "dependencies": {
    "better-auth": "^1.2.0",
    "@auth/drizzle-adapter": "^1.0.0",
    "drizzle-orm": "^0.35.0",
    "pg": "^8.12.0",
    "@nestjs/common": "^10.0.0",
    "@nestjs/core": "^10.0.0",
    "@nestjs/config": "^3.0.0"
  },
  "devDependencies": {
    "drizzle-kit": "^0.24.0",
    "@types/pg": "^8.11.0"
  }
}

Frontend Dependencies

前端依赖

json
{
  "dependencies": {
    "better-auth": "^1.2.0",
    "next": "^15.0.0",
    "react": "^19.0.0",
    "react-dom": "^19.0.0"
  }
}
json
{
  "dependencies": {
    "better-auth": "^1.2.0",
    "next": "^15.0.0",
    "react": "^19.0.0",
    "react-dom": "^19.0.0"
  }
}

Database

数据库

  • PostgreSQL 14+ recommended
  • For local development: Docker PostgreSQL or Postgres.app
  • 推荐使用PostgreSQL 14+
  • 本地开发可使用Docker PostgreSQL或Postgres.app

Troubleshooting

故障排除

1. "Session not found" errors

1. "会话未找到"错误

Problem: Session data is not being persisted or retrieved correctly.
Solution:
  • Verify database connection is working
  • Check session table exists and has data
  • Ensure
    BETTER_AUTH_SECRET
    is set consistently
  • Verify cookie domain settings match your application domain
问题:会话数据未正确持久化或获取。
解决方案
  • 验证数据库连接正常
  • 检查会话表是否存在且有数据
  • 确保
    BETTER_AUTH_SECRET
    在所有环境中一致
  • 验证Cookie域名设置与应用域名匹配

2. OAuth callback fails with "Invalid state"

2. OAuth回调返回"无效状态"

Problem: OAuth state mismatch during callback.
Solution:
  • Clear cookies and try again
  • Ensure
    BETTER_AUTH_URL
    is set correctly in environment
  • Check that redirect URI in OAuth app matches exactly
  • Verify no reverse proxy is modifying callbacks
问题:OAuth回调过程中状态不匹配。
解决方案
  • 清除Cookie后重试
  • 确保环境变量中
    BETTER_AUTH_URL
    设置正确
  • 检查OAuth应用中的重定向URI是否完全匹配
  • 验证反向代理未修改回调请求

3. TypeScript type errors with auth()

3. auth()函数出现TypeScript类型错误

Problem: Type inference not working correctly.
Solution:
  • Ensure TypeScript 5+ is installed
  • Use
    npx better-auth typegen
    to generate types
  • Restart TypeScript server in your IDE
  • Check that
    better-auth
    versions match on frontend and backend
问题:类型推断未正常工作。
解决方案
  • 确保安装了TypeScript 5+
  • 使用
    npx better-auth typegen
    生成类型
  • 重启IDE中的TypeScript服务器
  • 检查前后端
    better-auth
    版本是否一致

4. Migration fails with "table already exists"

4. 迁移时出现"表已存在"错误

Problem: Drizzle migration conflicts.
Solution:
  • Drop existing tables and re-run migration
  • Or use
    drizzle-kit push
    for development
  • For production, write manual migration to handle existing tables
问题:Drizzle迁移冲突。
解决方案
  • 删除现有表后重新运行迁移
  • 开发环境中使用
    drizzle-kit push
  • 生产环境中编写手动迁移以处理现有表

5. CORS errors from frontend to backend

5. 前端到后端出现CORS错误

Problem: Frontend cannot communicate with backend auth endpoints.
Solution:
  • Configure CORS in NestJS backend
  • Add frontend origin to allowed origins
  • Ensure credentials are included:
    credentials: 'include'
问题:前端无法与后端认证端点通信。
解决方案
  • 在NestJS后端配置CORS
  • 将前端源添加到允许的源列表中
  • 确保包含凭证:
    credentials: 'include'

6. Social provider returns "redirect_uri_mismatch"

6. 社交提供商返回"redirect_uri_mismatch"

Problem: OAuth app configuration mismatch.
Solution:
  • Update OAuth app with exact callback URL
  • Include both http://localhost and production URLs
  • For ngrok/local testing, update OAuth app each time URL changes
问题:OAuth应用配置不匹配。
解决方案

Resources

资源

Documentation

文档

Reference Implementations

参考实现

  • See
    references/nestjs-setup.md
    for complete NestJS setup
  • See
    references/nextjs-setup.md
    for complete Next.js setup
  • See
    references/plugins.md
    for plugin configuration
  • See
    assets/
    for example code files
  • 查看
    references/nestjs-setup.md
    获取完整NestJS配置
  • 查看
    references/nextjs-setup.md
    获取完整Next.js配置
  • 查看
    references/plugins.md
    获取插件配置
  • 查看
    assets/
    目录获取示例代码文件

Environment Variables

环境变量

See
Assets/env.example
for all required environment variables.
查看
Assets/env.example
获取所有必填环境变量。

Environment Variables

环境变量

bash
undefined
bash
undefined

Database

数据库

DATABASE_URL=postgresql://user:password@localhost:5432/dbname
DATABASE_URL=postgresql://user:password@localhost:5432/dbname

Better Auth

Better Auth

BETTER_AUTH_SECRET=your-secret-key-min-32-chars BETTER_AUTH_URL=http://localhost:3000
BETTER_AUTH_SECRET=your-secret-key-min-32-chars BETTER_AUTH_URL=http://localhost:3000

OAuth Providers

OAuth提供商

AUTH_GITHUB_CLIENT_ID=your-github-client-id AUTH_GITHUB_CLIENT_SECRET=your-github-client-secret
AUTH_GOOGLE_CLIENT_ID=your-google-client-id AUTH_GOOGLE_CLIENT_SECRET=your-google-client-secret
AUTH_GITHUB_CLIENT_ID=your-github-client-id AUTH_GITHUB_CLIENT_SECRET=your-github-client-secret
AUTH_GOOGLE_CLIENT_ID=your-google-client-id AUTH_GOOGLE_CLIENT_SECRET=your-google-client-secret

Email (for magic links and verification)

邮箱(用于魔法链接和验证)

SMTP_HOST=smtp.example.com SMTP_PORT=587 SMTP_USER=your-smtp-user SMTP_PASSWORD=your-smtp-password SMTP_FROM=noreply@example.com
SMTP_HOST=smtp.example.com SMTP_PORT=587 SMTP_USER=your-smtp-user SMTP_PASSWORD=your-smtp-password SMTP_FROM=noreply@example.com

Session (optional, for Redis)

会话(可选,用于Redis)

REDIS_URL=redis://localhost:6379
undefined
REDIS_URL=redis://localhost:6379
undefined