12k
All articles

BetterAuthでソーシャルログインを追加する方法

BetterAuthでTypeScriptアプリにソーシャルログインを追加し、Google・GitHubプロバイダーの設定とGeneric OAuthプラグインの活用方法を紹介する。

OpenReplay Team
OpenReplay Team
BetterAuthでソーシャルログインを追加する方法

ソーシャル認証は現代のWebアプリケーションにおいて標準となっていますが、多くの開発者は依然として古いAuth.jsのドキュメントや高額なSaaSソリューションに苦労しています。フレームワークに依存しないTypeScript認証ライブラリであるBetterAuthは、現在バージョン1.xとなり、強力かつ実装が簡単なセルフホスト型の代替手段を提供します。

重要なポイント

  • BetterAuthは、シンプルなOAuth2統合を備えたTypeScriptファーストのセルフホスト型認証ソリューションを提供します
  • サーバー側でソーシャルプロバイダーを設定し、クライアント側で統一されたsignIn.social() APIを使用します
  • Generic OAuthプラグインにより、あらゆるOAuth 2.0またはOIDC準拠プロバイダーとの統合が可能です
  • セッション管理とトークン処理は、リアクティブコンポーネントですぐに使用できます

BetterAuthとは?

BetterAuthは、自社のインフラストラクチャ上で動作するTypeScriptファーストの認証ライブラリです。複雑なアダプターパターンを持つNextAuth(現在のAuth.js)や、価格設定に縛られるClerkのようなSaaSプロバイダーとは異なり、BetterAuthはsocialProviders設定を通じてBetterAuthでのOAuth2のビルトインサポートを備えたクリーンなAPIを提供します。

このライブラリはそのシンプルさで際立っています。サーバー側でプロバイダーを設定し、createAuthClientでクライアントを作成し、authClient.signIn.social()を呼び出すだけです。別々のサインアップエンドポイントも、複雑なフローも不要で、ただ動作する認証を実現します。

BetterAuthソーシャルログインのセットアップ

サーバー設定

まずBetterAuthをインストールし、BetterAuthでのGoogleとGitHubログインを使用して認証サーバーを設定します:

// auth.ts
import { betterAuth } from "better-auth"
import { drizzleAdapter } from "better-auth/adapters/drizzle"
import { db } from "./db"

export const auth = betterAuth({
  database: drizzleAdapter(db, {
    provider: "sqlite"
  }),
  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!,
    }
  }
})

この設定により、OAuth2フローが自動的に処理されます。BetterAuthはOAuth交換とセッション作成を処理しますが、各プロバイダーのダッシュボードで正しいコールバックURLを設定する必要があります。

クライアントセットアップ

フロントエンドでBetterAuthソーシャルログインを有効にするために、認証クライアントを作成します:

// auth-client.ts
import { createAuthClient } from "better-auth/client"

export const authClient = createAuthClient({
  baseURL: process.env.NEXT_PUBLIC_APP_URL // アプリのベースURL
})

Next.jsでのソーシャルログイン実装

シンプルなログインコンポーネントを使用したNext.jsソーシャル認証の実装方法は以下の通りです:

// components/login-button.tsx
import { authClient } from "@/lib/auth-client"

export function LoginButton() {
  const handleGoogleLogin = async () => {
    await authClient.signIn.social({
      provider: "google",
      callbackURL: "/dashboard"
    })
  }

  const handleGitHubLogin = async () => {
    await authClient.signIn.social({
      provider: "github",
      callbackURL: "/dashboard"
    })
  }

  return (
    <div className="flex gap-4">
      <button onClick={handleGoogleLogin}>
        Googleでサインイン
      </button>
      <button onClick={handleGitHubLogin}>
        GitHubでサインイン
      </button>
    </div>
  )
}

signIn.social()メソッドがすべてを処理します:プロバイダーへのリダイレクト、コールバックの処理、セッションの確立です。認証失敗時のerrorCallbackURLや初回ユーザー向けのnewUserCallbackURLをオプションで指定できます。

Generic OAuthプラグインによるカスタムOAuthプロバイダー

ビルトインプロバイダー以外のプロバイダーについては、BetterAuthがBetterAuthのGeneric OAuthプラグインを提供しています。このプラグインにより、あらゆるOAuth 2.0またはOIDC準拠プロバイダーとの統合が可能になります:

// auth.ts with custom provider
import { betterAuth } from "better-auth"
import { genericOAuth } from "better-auth/plugins"

export const auth = betterAuth({
  plugins: [
    genericOAuth({
      config: [{
        providerId: "custom-provider",
        discoveryUrl: "https://provider.com/.well-known/openid-configuration",
        clientId: process.env.CUSTOM_CLIENT_ID!,
        clientSecret: process.env.CUSTOM_CLIENT_SECRET!,
        scopes: ["openid", "email", "profile"]
      }]
    })
  ]
})

この柔軟性により、主流のプロバイダーに限定されることはありません。エンタープライズSSO、地域サービス、内部OAuthサーバーなど、すべてシームレスに動作します。

セッション管理とトークン処理

BetterAuthは、すぐに使えるリアクティブなセッション管理を提供します:

// components/user-profile.tsx
import { authClient } from "@/lib/auth-client"

export function UserProfile() {
  const { data: session, isPending } = authClient.useSession()

  if (isPending) return <div>読み込み中...</div>
  if (!session) return <div>未認証</div>

  return (
    <div>
      <p>ようこそ、{session.user.name}さん</p>
      <button onClick={() => authClient.signOut()}>
        サインアウト
      </button>
    </div>
  )
}

トークンに関する注意点:リフレッシュトークンの動作はプロバイダーによって異なります。例えば、GitHubはデフォルトでリフレッシュトークンを提供しませんが、Googleは提供します。BetterAuthはこれらの違いを透過的に処理しますが、プロバイダー固有の仕様を理解しておくことで、エッジケースのデバッグに役立ちます。

本番環境での考慮事項

BetterAuthソーシャル認証をデプロイする際の注意点:

  1. 環境変数: OAuth認証情報を適切に保護する
  2. コールバックURL: 本番環境のURLでプロバイダー設定を更新する
  3. データベースマイグレーション: BetterAuthスキーマの更新後、通常のデータベースマイグレーションを実行する(例:Drizzle使用時はnpx @better-auth/cli generate経由)
  4. HTTPS: OAuth2は本番環境で安全な接続を必要とする

アカウントリンク(複数のソーシャルアカウントを1人のユーザーに接続すること)は、BetterAuthで進化中の機能です。ライブラリは基本的なケースをうまく処理しますが、複雑なシナリオではカスタムロジックが必要になる場合があります。

まとめ

BetterAuthは、Auth.jsの複雑さやSaaSプロバイダーのコストなしに、モダンでTypeScriptファーストの認証をスタックにもたらします。主要プロバイダーのビルトインサポートと、カスタム統合のためのGeneric OAuthプラグインにより、遭遇するほぼすべてのBetterAuthでのOAuth2シナリオをカバーします。

統一されたsignIn.social() API、リアクティブなセッション管理、フレームワークに依存しない設計により、BetterAuthは開発者の生産性を維持しながら認証インフラストラクチャを制御したいチームにとって堅実な選択肢となります。

よくある質問

パフォーマンスとバンドルサイズの観点で、BetterAuthはNextAuthとどう比較されますか?

BetterAuthは、モジュラーアーキテクチャとTypeScriptファーストのアプローチにより、通常バンドルサイズが小さくなります。基本的な操作のパフォーマンスは同等ですが、BetterAuthのよりシンプルなAPIは、より高速な実装とランタイムエラーの減少につながることが多いです。

例で示されているSQLite以外のデータベースでBetterAuthを使用できますか?

はい、BetterAuthはDrizzle ORMを通じて、PostgreSQL、MySQL、MongoDBを含む複数のデータベースアダプターをサポートしています。drizzleAdapter設定のproviderオプションをデータベースタイプに合わせて変更するだけです。

ユーザーが既に別のアカウントにリンクされているソーシャルプロバイダーでサインインしようとした場合、どうなりますか?

BetterAuthはデフォルトで基本的なアカウントリンクを自動的に処理し、重複アカウントを防ぎます。既存アカウントのマージなどの複雑なシナリオについては、BetterAuthのフックとミドルウェアシステムを使用してカスタムロジックを実装する必要があります。

BetterAuthでOAuthトークンのリフレッシュを手動で処理する必要がありますか?

いいえ、BetterAuthはプロバイダーから利用可能な場合、トークンリフレッシュを自動的に処理します。ライブラリはトークンのライフサイクルを透過的に管理しますが、GitHubなど一部のプロバイダーはデフォルトでリフレッシュトークンを提供しません。

DevTools for the frontend

Gain Debugging Superpowers

Unleash the power of session replay to reproduce bugs, track slowdowns and uncover frustrations in your app. Get complete visibility into your frontend with OpenReplay — the most advanced open-source session replay tool for developers.

Star on GitHub12k

We use cookies to improve your experience. By using our site, you accept cookies.