🔐
Svelte + Suapbase Auth Google/Github
💡Tips
SvelteにGithub SignInとGoogle SignInを実装してみた。自分のメモ用に記事を書いておく。
公式は個人のブログを参考に実装した。
認証システムのドキュメント
概要
このアプリケーションでは、Supabaseを使用してソーシャルログイン認証を実装しています。現在はGitHub認証を使用していますが、将来的な拡張性を考慮してGoogle認証の実装方法も記録しています。
現在の実装 (GitHub認証)
GitHubログイン実装
async function signInWithGithub() {
try {
loading = true;
error = null;
const { data, error: signInError } = await supabase.auth.signInWithOAuth({
provider: "github",
options: {
redirectTo: `${window.location.origin}/auth/callback`,
skipBrowserRedirect: true,
}
});
if (signInError) throw signInError;
if (data?.url) {
window.location.href = data.url;
}
} catch (e) {
if (e instanceof Error) {
error = e.message;
}
console.error("ログインエラー:", e);
} finally {
loading = false;
}
}
セットアップ手順
- Supabaseダッシュボードで「Authentication > Providers」を開く
- GitHubプロバイダーを有効化
- GitHubのOAuth Appsを作成
- Settings > Developer settings > OAuth Apps
- Authorization callback URL:
https://[PROJECT_REF].supabase.co/auth/v1/callback
将来の実装参考 (Google認証)
Googleログイン実装
async function signInWithGoogle() {
try {
loading = true;
error = null;
const { data, error: signInError } = await supabase.auth.signInWithOAuth({
provider: "google",
options: {
redirectTo: `${window.location.origin}/auth/callback`,
skipBrowserRedirect: true,
queryParams: {
access_type: 'offline',
prompt: 'consent'
}
}
});
if (signInError) throw signInError;
if (data?.url) {
window.location.href = data.url;
}
} catch (e) {
if (e instanceof Error) {
error = e.message;
}
console.error("ログインエラー:", e);
} finally {
loading = false;
}
}
Google認証セットアップ手順
- Supabaseダッシュボードで「Authentication > Providers」を開く
- Googleプロバイダーを有効化
- Google Cloud Consoleでプロジェクトを作成
- OAuth 2.0クライアントIDを作成
- 承認済みのリダイレクトURI:
https://[PROJECT_REF].supabase.co/auth/v1/callback
- 承認済みのリダイレクトURI:
- 取得したクライアントIDとシークレットをSupabaseに設定
コールバック処理
認証後のコールバック処理は以下のファイルで実装されています:
/src/routes/auth/callback/+page.svelte
onMount(async () => {
try {
if (!browser) return;
// 認証状態が安定するまで待機
await new Promise(resolve => setTimeout(resolve, 1000));
// セッションの取得
const { data: { session }, error: sessionError } = await supabase.auth.getSession();
if (sessionError) throw sessionError;
if (!session) {
throw new Error('セッションが見つかりません');
}
// ユーザー情報の取得と更新
const { data: { user }, error: userError } = await supabase.auth.getUser();
if (userError) throw userError;
if (user) {
// プロバイダー情報の更新
const currentProviders = user.app_metadata?.providers || [];
if (!currentProviders.includes(session.provider_token ? 'github' : 'google')) {
await supabase.auth.updateUser({
data: {
providers: [...currentProviders, session.provider_token ? 'github' : 'google']
}
});
}
}
// ダッシュボードへリダイレクト
await goto('/dashboard');
} catch (e) {
console.error('認証エラー:', e);
await goto('/');
}
});
注意点
- 複数のプロバイダーを同時に使用する場合、セッション管理に注意が必要
- リダイレクトURLは環境に応じて適切に設定
- エラーハンドリングを適切に実装
- ユーザーメタデータの更新は慎重に行う
トラブルシューティング
-
The message port closed before a response was received
エラーが発生した場合:-
skipBrowserRedirect: true
の設定を確認 - リダイレクトの処理を手動で行う
- コールバックページでの待機時間を調整
-
セキュリティ考慮事項
- 環境変数による認証情報の管理
- 適切なスコープの設定
- セッショントークンの安全な管理
- CORS設定の確認
Discussion