00 / 00

认证系统

Better Auth 配置、OAuth 提供商设置、手机号登录、Magic Link、2FA 和微信登录集成指南

概览

项目使用 Better Auth 作为认证框架。Better Auth 是一个开源的 TypeScript 认证库,帮你处理用户注册、登录、会话管理等核心功能,无需从零实现。

  • 配置位置: products/01mvp/packages/auth/src/index.ts
  • 环境变量: products/01mvp/packages/config/.env.local,跨产品共享配置为 packages/config/.env.local

登录方式一览

项目支持以下登录方式,默认已开启邮箱 + 密码登录,其余方式需配置对应环境变量后才会生效。微信登录还需要显式设置 AUTH_ENABLE_WECHAT=true

登录方式所需环境变量默认状态
邮箱 + 密码BETTER_AUTH_SECRET已开启
GitHub OAuthGITHUB_CLIENT_ID, GITHUB_CLIENT_SECRET未配置则隐藏
Google OAuthGOOGLE_CLIENT_ID, GOOGLE_CLIENT_SECRET未配置则隐藏
微信扫码 (PC)AUTH_ENABLE_WECHAT, WECHAT_WEBSITE_APP_ID, WECHAT_WEBSITE_APP_SECRET未开启或未配置则隐藏
微信授权 (手机)AUTH_ENABLE_WECHAT, WECHAT_SERVICE_ACCOUNT_APP_ID, WECHAT_SERVICE_ACCOUNT_APP_SECRET未开启或未配置则隐藏
微信小程序WECHAT_MINIPROGRAM_APP_ID, WECHAT_MINIPROGRAM_APP_SECRET未配置则隐藏
手机号 + 短信验证码ALIBABA_CLOUD_ACCESS_KEY_ID, ALIBABA_CLOUD_ACCESS_KEY_SECRET已开启(默认使用阿里云 PNVS)
Magic Link(邮件链接)AUTH_ENABLE_MAGIC_LINKS, ZEABUR_EMAIL_API_KEY, EMAIL_FROM默认关闭
用户名登录无需额外配置已开启
双因素认证 (2FA)AUTH_ENABLE_TWO_FACTOR已开启

环境变量配置

基础配置

这些变量是认证系统运行的必要条件。

# 必填:Better Auth 签名密钥(至少 32 字符,用于加密 session token)
BETTER_AUTH_SECRET=your-secret-key-min-32-chars

# 站点 URL 和 API URL
VITE_WEB_URL=http://localhost:7001
VITE_SERVER_URL=http://localhost:7001/api

# 可选:产品级 Cookie 前缀,默认由 @01mvp/config 提供
AUTH_COOKIE_PREFIX=01mvp-session

# 可选:跨子域名 Cookie(只在需要 SSO 时设置)
COOKIE_DOMAIN=.example.com

BETTER_AUTH_SECRET 在生产环境必须使用随机生成的强密钥,绝对不要使用示例中的值。可以用 openssl rand -base64 32 生成。

默认建议让 Cookie 保持 host-only,也就是不设置 COOKIE_DOMAIN。如果同一个顶级域名下有多个产品,比如 app.example.comstore.example.com,它们应该使用不同的 AUTH_COOKIE_PREFIX,避免会话 Cookie 互相覆盖。只有同一个产品明确要在多个子域共享登录态时,才设置 COOKIE_DOMAIN

OAuth 提供商配置

环境变量说明用于
GITHUB_CLIENT_IDGitHub OAuth App 的 Client IDGitHub 登录
GITHUB_CLIENT_SECRETGitHub OAuth App 的 Client SecretGitHub 登录
GOOGLE_CLIENT_IDGoogle Cloud Console 的 Client IDGoogle 登录
GOOGLE_CLIENT_SECRETGoogle Cloud Console 的 Client SecretGoogle 登录

微信登录配置

环境变量说明
AUTH_ENABLE_WECHAT是否启用微信登录,默认 false
WECHAT_WEBSITE_APP_ID微信开放平台网站应用 AppID(PC 扫码登录)
WECHAT_WEBSITE_APP_SECRET微信开放平台网站应用 AppSecret
WECHAT_SERVICE_ACCOUNT_APP_ID微信公众平台服务号 AppID(手机端授权)
WECHAT_SERVICE_ACCOUNT_APP_SECRET微信公众平台服务号 AppSecret
WECHAT_MINIPROGRAM_APP_ID微信小程序 AppID
WECHAT_MINIPROGRAM_APP_SECRET微信小程序 AppSecret

短信服务配置

当前模板的手机号登录默认使用阿里云短信认证服务(PNVS)。腾讯云和 Twilio 的 provider 代码保留在 @repo/sms 的显式 subpath 中,需要时由项目代码主动接入。

环境变量说明服务商
ALIBABA_CLOUD_ACCESS_KEY_ID阿里云 AccessKey ID阿里云 PNVS
ALIBABA_CLOUD_ACCESS_KEY_SECRET阿里云 AccessKey Secret阿里云 PNVS
ALIYUN_SMS_REGION阿里云 OpenAPI 地域(默认 cn-hangzhou阿里云 PNVS

邮件服务配置

环境变量说明
EMAIL_FROM发件人邮箱地址(用于验证邮件、Magic Link 等)
ZEABUR_EMAIL_API_KEYZeabur Email API 密钥

认证相关变量优先写在 products/01mvp/packages/config/.env.local。复制产品示例文件作为起点:cp products/01mvp/packages/config/.env.example products/01mvp/packages/config/.env.local

双因素认证 (2FA)

项目支持基于 TOTP(如 Google Authenticator)的双因素认证,通过 Better Auth 的 twoFactor 插件实现。开关由 AUTH_ENABLE_TWO_FACTOR 控制,默认 true

详细的 2FA 配置、数据库模型和客户端集成说明,见 双因素认证

管理员角色

项目的管理员系统和细粒度权限(SUPER_ADMIN / OPERATION_ADMIN)是安全基础设施的一部分。角色定义、权限列表和代码用法详见 管理员系统

Better Auth 插件一览

项目预装了以下 Better Auth 插件,开箱即用:

插件说明
admin管理员角色和权限管理
magicLink邮件魔法链接登录(无密码)
openAPI自动生成 OpenAPI 文档
twoFactor双因素认证(TOTP)
username用户名登录支持
phoneNumber手机号 + 短信验证码登录
wechatOAuth(自定义)微信 OAuth 登录(自定义插件)

在代码中使用

客户端:获取当前用户

在 React 组件中使用 useAuth hook 获取当前登录状态:

import { useAuth } from "@01mvp/auth/react/tanstack-start/hooks";

export function UserProfile() {
  const { user, isPending } = useAuth();

  if (isPending) return <div>加载中...</div>;
  if (!user) return <div>未登录</div>;

  return (
    <div>
      <p>用户名: {user.name}</p>
      <p>邮箱: {user.email}</p>
    </div>
  );
}

客户端:调用登录 API

浏览器侧统一用 @01mvp/auth/react/auth-client,不要在服务端直接用它(没有请求隔离):

import { authClient } from "@01mvp/auth/react/auth-client";

// 邮箱密码登录
await authClient.signIn.email({
  email: "user@example.com",
  password: "password123",
});

// GitHub 登录(跳转到 GitHub 授权页)
await authClient.signIn.social({ provider: "github" });

// 手机号验证码登录
await authClient.phoneNumber.sendOtp({ phoneNumber: "+8613800138000" });
await authClient.phoneNumber.verify({
  phoneNumber: "+8613800138000",
  code: "123456",
});

// Magic Link 登录
await authClient.signIn.magicLink({ email: "user@example.com" });

// 登出
await authClient.signOut();

服务端:在 oRPC / Hono 里用 session

服务端会话挂在请求上下文上。受保护的 oRPC 过程里直接读 context.session

import { isAdmin } from "@01mvp/auth/permissions";

// 受保护过程里
const userId = context.session.user.id;

// 管理员校验
if (!isAdmin(context.session.user)) {
  throw new Error("Forbidden");
}

路由保护、beforeLoad 和权限规则见 products/01mvp/packages/auth认证系统 子页。不要再按 Next.js Server Components / 自定义 @/modules/... 路径抄示例。

常见问题

各登录方式接入指南

相关资源

这篇文档有问题?