Open1

SupabaseでのGoogle認証実装:セッション持続時間の最適化と詳細な手順

MAAAAAAAAAAAMAAAAAAAAAAA
SupabaseでのGoogle認証実装:セッション持続時間の最適化と詳細な手順

Supabaseを使用してWebアプリケーションを開発する際、Google認証の実装は一般的な要件です。しかし、デフォルトの設定では、ユーザーセッションが短時間で終了してしまうという問題があります。この記事では、この問題を解決し、長期間持続するセッションを実現する方法を詳細に解説します。

目次

  1. はじめに
  2. 前提条件
  3. Google Cloud Platformの設定
  4. Supabaseの設定
  5. フロントエンドの実装
  6. バックエンドの実装
  7. セキュリティ考慮事項
  8. パフォーマンス最適化
  9. ユーザー体験の向上
  10. トラブルシューティング
  11. まとめ

はじめに

Supabaseは強力なバックエンドサービスですが、Google認証を使用する際、デフォルトではセッションの持続時間が1時間に制限されています。この記事では、この制限を克服し、より長期間のセッションを実現する方法を step by step で解説します。

前提条件

  • Supabaseプロジェクトが作成済みであること
  • Google Cloud Platformのプロジェクトが作成済みであること
  • 基本的なWeb開発の知識があること

Google Cloud Platformの設定

OAuth同意画面の設定

  1. Google Cloud Consoleにアクセスします。
  2. 左側のメニューから「APIとサービス」→「OAuth同意画面」を選択します。
  3. アプリ名、ユーザーサポートメール、開発者連絡先情報を入力します。
  4. 「承認済みドメイン」に<YOUR_PROJECT_ID>.supabase.coを追加します。
  5. 以下のスコープを追加します:
    • .../auth/userinfo.email
    • .../auth/userinfo.profile
    • openid

認証情報の作成

  1. 「認証情報」ページに移動します。
  2. 「認証情報を作成」→「OAuthクライアントID」を選択します。
  3. アプリケーションタイプで「ウェブアプリケーション」を選択します。
  4. 「承認済みのJavaScript生成元」に自サイトのURLを追加します。
  5. 「承認済みのリダイレクトURI」にSupabaseダッシュボードに表示されているコールバックURLを追加します。

Supabaseの設定

ダッシュボードでのGoogle認証の有効化

  1. Supabaseダッシュボードにアクセスします。
  2. 左側のメニューから「Authentication」→「Providers」を選択します。
  3. Google providerを有効化します。
  4. Google Cloud Platformで取得したクライアントIDとシークレットを入力します。

ローカル開発環境の設定

config.tomlファイルにGoogle認証の情報を追加します:

[auth.external.google]
enabled = true
client_id = "YOUR_GOOGLE_CLIENT_ID"
secret = "YOUR_GOOGLE_CLIENT_SECRET"

フロントエンドの実装

フロントエンドの実装には、アプリケーションコードを使用する方法と、Googleの事前構築されたサインインボタンを使用する方法の2つがあります。

アプリケーションコードを使用する方法

Supabaseクライアントの初期化

import { createClient } from '@supabase/supabase-js'

const supabase = createClient('YOUR_SUPABASE_URL', 'YOUR_SUPABASE_ANON_KEY')

サインイン機能の実装

async function signInWithGoogle() {
  const { data, error } = await supabase.auth.signInWithOAuth({
    provider: 'google',
    options: {
      queryParams: {
        access_type: 'offline',
        prompt: 'consent',
      },
    },
  })

  if (error) {
    console.error('Error during sign in:', error)
    return
  }

  console.log('Signed in successfully:', data)
}

トークンの保存

function saveTokens(session) {
  if (session) {
    const { provider_token, provider_refresh_token } = session
    // セキュアなストレージに保存(例: HttpOnly Cookie)
    document.cookie = `provider_token=${provider_token}; HttpOnly; Secure`
    document.cookie = `provider_refresh_token=${provider_refresh_token}; HttpOnly; Secure`
  }
}

セッションの更新

async function refreshSession() {
  const { data, error } = await supabase.auth.refreshSession()
  if (error) {
    console.error('Error refreshing session:', error)
    return
  }

  if (data?.session) {
    saveTokens(data.session)
  }
}

Googleの事前構築されたサインインボタンを使用する方法

HTMLの設定

<head>
  <script src="https://accounts.google.com/gsi/client" async defer></script>
</head>
<body>
  <div
    id="g_id_onload"
    data-client_id="YOUR_GOOGLE_CLIENT_ID"
    data-context="signin"
    data-ux_mode="popup"
    data-callback="handleSignInWithGoogle"
    data-auto_select="true"
    data-itp_support="true"
    data-use_fedcm_for_prompt="true"
  ></div>

  <div
    class="g_id_signin"
    data-type="standard"
    data-shape="pill"
    data-theme="outline"
    data-text="signin_with"
    data-size="large"
    data-logo_alignment="left"
  ></div>
</body>

コールバック関数の実装

async function handleSignInWithGoogle(response) {
  const { data, error } = await supabase.auth.signInWithIdToken({
    provider: 'google',
    token: response.credential,
  })

  if (error) {
    console.error('Error during sign in:', error)
    return
  }

  console.log('Signed in successfully:', data)
  saveTokens(data.session)
}

バックエンドの実装

Server-Side Rendering (SSR) を使用する場合、バックエンドでのコールバック処理が必要になります。以下は Next.js を使用した例です。

コールバックエンドポイントの作成

// pages/api/auth/callback.js
import { createServerSupabaseClient } from '@supabase/auth-helpers-nextjs'

export default async function handler(req, res) {
  const supabase = createServerSupabaseClient({ req, res })
  const { code } = req.query

  if (code) {
    await supabase.auth.exchangeCodeForSession(code)
  }

  res.redirect('/')
}

セキュリティ考慮事項

  1. トークンの安全な保存: クライアントサイドでのトークン保存は避け、HttpOnlyクッキーを使用しましょう。
  2. CSRF対策: ステート・パラメータを使用してCSRF攻撃を防止します。
  3. スコープの最小化: 必要最小限のスコープのみを要求するようにしましょう。

パフォーマンス最適化

  1. トークンの事前更新: アクセストークンの有効期限の75%経過時点でリフレッシュを実行することで、ユーザー体験を向上させることができます。
  2. エラーハンドリング: ネットワークエラーや認証エラーに対して適切にリトライするロジックを実装しましょう。

ユーザー体験の向上

  1. ローディング状態の表示: 認証処理中はローディングインジケータを表示し、ユーザーに進行状況を伝えましょう。
  2. エラーメッセージの適切な表示: 技術的なエラーメッセージではなく、ユーザーフレンドリーなメッセージを提供しましょう。

トラブルシューティング

よくある問題とその解決策:

  1. リダイレクトURIの不一致: Google Cloud PlatformとSupabaseの設定を再確認してください。
  2. スコープの設定ミス: 必要なスコープが正しく設定されているか確認してください。
  3. クライアントIDまたはシークレットの誤り: 入力値を再確認してください。

デバッグ方法:

  • ブラウザの開発者ツールを使用してネットワークリクエストを確認します。
  • Supabaseのログを活用してエラーを特定します。

まとめ

SupabaseとGoogle認証を組み合わせて使用する際、適切な設定とトークン管理が重要です。この記事で紹介した方法を使用することで、セキュアで長期間持続するセッションを実現できます。ユーザー体験とセキュリティのバランスを取りながら、アプリケーションの要件に合わせて実装を最適化していきましょう。