Better Auth で Web アプリに認証機能を追加する方法

Chris ChenChris Chen
10 分読む
Dec 29, 2025

sveltekit & better auth

認証は、ほぼすべての Web アプリケーションにおいて重要な機能です。SaaS 製品、個人プロジェクト、社内ツールのいずれを構築する場合でも、ユーザーのサインイン機能が必要になることがほとんどです。

しかし、認証をゼロから実装するのは簡単ではありません。パスワードの安全なハッシュ化、セッション管理、OAuth フロー、トークンの更新など、問題が発生しやすい要素が数多くあります。認証は重要ですが、アプリを差別化する機能ではありません。他の部分に時間を使いたいと思うのが自然です。

そこで Better Auth の出番です。

Better Auth は、Web アプリケーションの認証を簡素化するために設計された、TypeScript ファーストの認証ライブラリです。

柔軟性、移植性、開発者に優しい API を重視しています:

  • フレームワーク非依存: SvelteKit、Next.js、Nuxt、Express などのフレームワークと統合可能
  • ソーシャルプロバイダー内蔵: Google、GitHub、Discord、Twitter などの一般的な OAuth プロバイダーに対応
  • シンプルな API: 一般的な認証シナリオに対して、最小限の設定で利用可能
  • ベンダーロックインなし: データベースに依存せず、さまざまなプラットフォームにデプロイ可能

このガイドでは、Better Auth を SvelteKit に統合する手順を説明します。最終的には、ソーシャルログインに対応した認証システムが完成します。

SvelteKit との統合

1. インストールとセットアップ

まず、新しい SvelteKit プロジェクトを作成します(既存のプロジェクトを使用することも可能です):

npx sv create my-app
cd my-app

Better Auth をインストールします:

npm install better-auth

次に、環境変数を設定します。プロジェクトのルートディレクトリに  .env  ファイルを作成します:

# Better Auth Secret Key
BETTER_AUTH_SECRET=your-better-auth-secret

# GitHub OAuth
GITHUB_CLIENT_ID=your-github-client-id
GITHUB_CLIENT_SECRET=your-github-client-secret

# Google OAuth
GOOGLE_CLIENT_ID=your-google-client-id
GOOGLE_CLIENT_SECRET=your-google-client-secret

 BETTER_AUTH_SECRET  を生成するには、ターミナルで以下のコマンドを実行します:

openssl rand -base64 32

OAuth 認証情報の取得方法:

コールバック URL を  http://localhost:5173/api/auth/callback/github (Google の場合は  /google )に設定します。

2. サーバー設定

サーバー側で auth インスタンスを作成します。ここでプロバイダーと設定を定義します。

 src/lib/server/auth.ts  を作成します:

import { betterAuth } from 'better-auth';
import { env } from '$env/dynamic/private';

export const auth = betterAuth({
	secret: env.BETTER_AUTH_SECRET,
	socialProviders: {
		github: {
			clientId: env.GITHUB_CLIENT_ID as string,
			clientSecret: env.GITHUB_CLIENT_SECRET as string
		},
		google: {
			clientId: env.GOOGLE_CLIENT_ID as string,
			clientSecret: env.GOOGLE_CLIENT_SECRET as string
		}
	}
});

次に API ルートハンドラーを作成します。Better Auth はキャッチオールルートを使用して、認証関連のすべてのリクエストを処理します。

 src/routes/api/auth/[...all]/+server.ts  を作成します:

import { auth } from '$lib/server/auth';
import type { RequestHandler } from './$types';

export const GET: RequestHandler = async ({ request }) => {
    return auth.handler(request);
};

export const POST: RequestHandler = async ({ request }) => {
    return auth.handler(request);
};

サーバー側の設定は以上です。Better Auth は  /api/auth/*  ルートを自動的に処理します。

3. クライアント設定

Svelte コンポーネントで使用する auth クライアントを作成します。

 src/lib/auth-client.ts  を作成します:

import { createAuthClient } from 'better-auth/svelte';

export const authClient = createAuthClient();

クライアントは認証エンドポイントを自動的に検出します。これで、アプリ内のどこでも  authClient を使用してサインインやサインアウトを実行できます。

4. ソーシャルログインの実装

まず、 src/hooks.server.ts  を作成して、各リクエストでユーザーセッションを取得します:

import { auth } from '$lib/server/auth';
import type { Handle } from '@sveltejs/kit';

export const handle: Handle = async ({ event, resolve }) => {
    const session = await auth.api.getSession({
        headers: event.request.headers
    });

    event.locals.session = session;

    return resolve(event);
};

 locals  の型定義を追加します。 src/app.d.ts  を更新します:

import type { auth } from '$lib/server/auth';

declare global {
	namespace App {
		interface Locals {
			session: typeof auth.$Infer.Session | null;
		}
	}
}

export {};

次に、セッションデータをすべてのページに渡す layout server load 関数を作成します。

 src/routes/+layout.server.ts  を作成します:

import type { LayoutServerLoad } from './$types';

export const load: LayoutServerLoad = async ({ locals }) => {
    return {
        session: locals.session
    };
};

ログインページを作成します。 src/routes/login/+page.svelte  を作成します:

<script lang="ts">
    import { authClient } from '$lib/auth-client';

    const signInWithGitHub = async () => {
        await authClient.signIn.social({
            provider: 'github',
            callbackURL: '/'
        });
    };
    
    const signInWithGoogle = async () => {
        await authClient.signIn.social({
            provider: 'google',
            callbackURL: '/'
        });
    };
</script>

<div class="login-container">
    <h1>Sign In</h1>
    <button onclick={signInWithGitHub}>Continue with GitHub</button>
    <button onclick={signInWithGoogle}>Continue with Google</button>
</div>

ユーザー情報の表示とサインアウト処理のために、layout コンポーネントを更新します。 src/routes/+layout.svelte  を編集します:

<script lang="ts">
    import { authClient } from '$lib/auth-client';

    let { data, children } = $props();

    const signOut = async () => {
        await authClient.signOut();
    };
</script>

<header>
    {#if data.session}
        <p>Welcome, {data.session.user.name}!</p>
        <button onclick={signOut}>Sign Out</button>
    {:else}
        <a href="/login">Sign In</a>
    {/if}
</header>

<main>
    {@render children()}
</main>

この方法は SSR に対応しています。セッションデータはページ読み込み時にすぐに利用可能で、未認証コンテンツのちらつきが発生しません。

5. ルート保護

特定のルートを保護するには、 src/hooks.server.ts  を更新して、ページのレンダリング前に認証を確認します:

import { auth } from '$lib/server/auth';
import { redirect, type Handle } from '@sveltejs/kit';

const protectedRoutes = ['/dashboard', '/settings', '/profile'];

export const handle: Handle = async ({ event, resolve }) => {
    const session = await auth.api.getSession({
        headers: event.request.headers
    });

    event.locals.session = session;

    const isProtected = protectedRoutes.some((route) => event.route.id?.startsWith(route));

    if (isProtected && !session) {
        throw redirect(303, '/login');
    }

    return resolve(event);
};

これで、 /dashboard /settings /profile  で始まるルートは、未認証ユーザーをログインページにリダイレクトします。

6. データベース(オプション)

デフォルトでは、Better Auth はセッションをメモリに保存します。開発環境ではこれで問題ありませんが、本番環境ではサーバー再起動後もユーザーデータを保持するためにデータベースが必要です。

Better Auth は Prisma、Drizzle、MongoDB など、複数のデータベースアダプターをサポートしています。

Prisma を使用した例を示します:

import { betterAuth } from 'better-auth';
import { prismaAdapter } from 'better-auth/adapters/prisma';
import { PrismaClient } from '@prisma/client';

const prisma = new PrismaClient();

export const auth = betterAuth({
  database: prismaAdapter(prisma, {
    provider: 'sqlite', // or mysql, postgresql
  }),
  socialProviders: {
    // ... your providers
  }
});

データベース設定の詳細については、Better Auth データベースドキュメント を参照してください。

クイックスタートテンプレート

すぐに始めたい場合は、すべて設定済みの SvelteKit + Better Auth テンプレートを用意しています:

  • GitHub、Google、Discord、Slack、Vercel OAuth 設定済み
  • SSR 対応のセッション管理
  • ルート保護のサンプル
  • 環境変数テンプレート

👉 EdgeOne Pages にデプロイ

まとめ

認証の追加は複雑である必要はありません。Better Auth と SvelteKit を使えば、1 時間以内に完全なソーシャルログインシステムを構築できます。

このガイドで説明した内容:

  • SvelteKit プロジェクトでの Better Auth の設定
  • Google と GitHub OAuth プロバイダーの設定
  • サインイン/サインアウト機能の構築
  • server hooks によるルート保護
  • 本番環境向けのデータベース設定(オプション)

さらに速く始めたい場合は、テンプレートを使ってワンクリックでデプロイできます。