はじめに
認証機能の実装、正直なところ毎回面倒だと思いませんか。
GitHubで23,000スター以上、毎月200万回以上のnpmダウンロード。Better Authは今、TypeScriptエコシステムで最も勢いのある認証フレームワークになっています。
個人的には、Auth.jsやNextAuthで「あれ、これ以上のことやりたいときどうすんの」と思った経験がある人には刺さると思います。基本的な認証はどのライブラリでもできるんですよ。でも、2FAとかマルチテナントとか、ちょっと踏み込んだ機能を実装しようとすると途端にコード量が増える。Better Authはその辺を最初から考慮して設計されているので、追加機能の実装が楽なんですね。
Better Authとは
Better Authは「TypeScript向けの最も包括的な認証フレームワーク」を標榜するライブラリです。
2024年に登場してから急速に成長し、現在はv1.4.6がリリースされています。MIT Licenseで公開されており、673人以上のコントリビューターが開発に参加しています。
特筆すべきは「フレームワーク非依存」という設計思想。Next.jsでもHonoでもExpressでも、好きなフレームワークで使えます。これ、意外と重要で、プロジェクトの技術スタックに縛られずに認証ロジックを共通化できるんですよ。
特徴・メリット
1. 本当に包括的な機能セット
標準で対応している認証方式が豊富です:
- メールとパスワード認証
- ソーシャルログイン(Google、GitHub、Apple、その他多数)
- 2FA(二要素認証)
- パスキー
- マジックリンク
- SSO(シングルサインオン)
- マルチテナント
正直、これだけ揃っていれば大抵のプロジェクトは対応できます。
2. プラグインエコシステム
「でも特殊な要件があるんだよね」という人のために、プラグインで機能を拡張できる仕組みがあります。username認証、email-otp、Stripe連携など、必要なものだけ追加できる。
余計なものを入れずに済むので、バンドルサイズも抑えられます。コスパ的にいい設計。
3. TypeScriptファースト
最初からTypeScriptで書かれているので、型サポートが完璧。補完がしっかり効くし、設定ミスもコンパイル時に気づける。
30代になって思うのは、型安全性って地味だけど開発効率に直結するということ。
4. 複数のデータベースに対応
SQLite、PostgreSQL、MySQL、MongoDBなど、主要なデータベースに対応。ORMを使っている場合も、Prisma、Drizzle、Typegooseなどのアダプタが用意されています。
既存プロジェクトへの導入がしやすいのは大きなメリット。
5. セッション管理が柔軟
JWTベースとデータベースセッション、両方に対応。プロジェクトの要件に合わせて選べます。
インストール方法
パッケージのインストール
npm install better-auth
pnpmやyarn、bunでも同様にインストールできます。
# pnpm
pnpm add better-auth
# yarn
yarn add better-auth
# bun
bun add better-auth
環境変数の設定
.envファイルに以下を追加します。
BETTER_AUTH_SECRET=your-secret-key-32-characters-or-more
BETTER_AUTH_URL=http://localhost:3000
BETTER_AUTH_SECRETは32文字以上の高エントロピーな値を設定してください。本番環境では特に重要。
認証インスタンスの作成
auth.tsファイルを作成します。
import { betterAuth } from "better-auth";
import Database from "better-sqlite3";
export const auth = betterAuth({
database: new Database("./sqlite.db"),
emailAndPassword: {
enabled: true,
},
});
これだけで基本的な認証が動きます。時短になる。
基本的な使い方
メールとパスワード認証の設定
import { betterAuth } from "better-auth";
export const auth = betterAuth({
database: new Database("./sqlite.db"),
emailAndPassword: {
enabled: true,
},
});
クライアント側の設定
import { createAuthClient } from "better-auth/client";
export const authClient = createAuthClient({
baseURL: "http://localhost:3000",
});
サインアップの実装
const handleSignUp = async () => {
const { data, error } = await authClient.signUp.email({
email: "user@example.com",
password: "securepassword",
name: "John Doe",
callbackURL: "/dashboard",
}, {
onSuccess: (ctx) => {
// 登録成功時の処理
console.log("登録完了");
},
onError: (ctx) => {
// エラー時の処理
alert(ctx.error.message);
},
});
};
サインインの実装
const handleSignIn = async () => {
const { data, error } = await authClient.signIn.email({
email: "user@example.com",
password: "securepassword",
callbackURL: "/dashboard",
rememberMe: true,
});
};
セッションの取得
Reactの場合、hooksで簡単に取得できます。
function Dashboard() {
const { data: session, isPending } = authClient.useSession();
if (isPending) {
return <div>Loading...</div>;
}
if (!session) {
return <div>ログインしてください</div>;
}
return <div>ようこそ、{session.user.name}さん</div>;
}
実践的なユースケース
ソーシャルログインの追加
GitHubログインを追加する例。
export const auth = betterAuth({
database: new Database("./sqlite.db"),
emailAndPassword: {
enabled: true,
},
socialProviders: {
github: {
clientId: process.env.GITHUB_CLIENT_ID!,
clientSecret: process.env.GITHUB_CLIENT_SECRET!,
},
google: {
clientId: process.env.GOOGLE_CLIENT_ID!,
clientSecret: process.env.GOOGLE_CLIENT_SECRET!,
},
},
});
クライアント側でソーシャルログインを実行:
const handleGitHubLogin = async () => {
await authClient.signIn.social({
provider: "github",
callbackURL: "/dashboard",
});
};
PostgreSQLとの連携
本番環境ではPostgreSQLを使うことが多いと思います。
import { betterAuth } from "better-auth";
import { Pool } from "pg";
export const auth = betterAuth({
database: new Pool({
connectionString: process.env.DATABASE_URL,
}),
emailAndPassword: {
enabled: true,
},
});
保護されたルートの作成
Next.jsのミドルウェアで認証チェックを行う例。
import { auth } from "@/lib/auth";
import { NextResponse } from "next/server";
import type { NextRequest } from "next/server";
export async function middleware(request: NextRequest) {
const session = await auth.api.getSession({
headers: request.headers,
});
if (!session) {
return NextResponse.redirect(new URL("/login", request.url));
}
return NextResponse.next();
}
export const config = {
matcher: ["/dashboard/:path*", "/settings/:path*"],
};
2FAの実装
プラグインを使って二要素認証を追加。
import { betterAuth } from "better-auth";
import { twoFactor } from "better-auth/plugins";
export const auth = betterAuth({
database: new Database("./sqlite.db"),
plugins: [
twoFactor({
issuer: "MyApp",
}),
],
});
QOL上がるのは、こういう高度な機能が数行で追加できるところ。
Auth.jsとの比較
Auth.js(旧NextAuth)を使っている人も多いと思うので、簡単に比較しておきます。
| 項目 | Better Auth | Auth.js |
|---|---|---|
| フレームワーク依存 | 非依存 | Next.js中心 |
| 2FA | 標準対応 | 自前実装 |
| マルチテナント | プラグインで対応 | 自前実装 |
| 型サポート | 完全 | 部分的 |
| 学習コスト | 低め | 低め |
個人的には、Next.js以外も視野に入れているならBetter Auth一択ですね。Next.jsオンリーでシンプルな認証だけならAuth.jsでも十分。
まとめ
Better Authを触ってみて感じたこと:
- セットアップ: 10分で基本的な認証が動く
- 拡張性: プラグインで2FAもSSOも追加できる
- TypeScript: 型サポートが完璧でストレスフリー
- フレームワーク非依存: 技術スタックを選ばない
- ドキュメント: 充実していて迷わない
正直なところ、「認証実装、また一からやるのか」という憂鬱さがかなり軽減されました。
特に、基本的な認証だけじゃなくて2FAやマルチテナントまで見据えているプロジェクトには最適だと思います。Auth.jsで「これ以上は自前で実装か」と思った経験がある人は、一度試してみる価値ありますよ。