このコードのリポジトリ
masakinihirota/nextjs_supabase
GitHub認証の動作確認済み
目的
Bolt.newというWebサービスでGitHub認証機能を作ってもらいましたが、どのように動いているのか実際のコードを確認します。
この記事では、SupabaseでGitHub認証を確認します。ローカル環境で動作させます。
前提知識
- Next.js 15
- Supabase (サーバー環境)
- Supabase (ローカル環境)
- TypeScript
- VSCode
- GitHub
Supabase (ローカル環境) ダッシュボード
Next.js インストール
npx create-next-app@latest --typescript --tailwind --eslint
[app name]
√ Would you like your code inside a `src/` directory? ... No / [Yes]
√ Would you like to use App Router? (recommended) ... No / [Yes]
√ Would you like to use Turbopack for `next dev`? ... No / [Yes]
√ Would you like to customize the import alias (`@/*` by default)? ... No / [Yes]
√ What import alias would you like configured? ... @/*
Next.jsの環境ファイル
※注意
環境変数のファイルは .env
というファイル名にしてください。
Next.jsの環境変数設定に関するトラブルシューティング
`.env.local` ファイルでは環境変数を読み込んでくれませんでした。(Windows10環境).env.local
の設定は正しいと信じ込み、他の場所を色々試しましたがundefined
となり、読み込んでくれませんでした。以前あったトラブルを思い出し、.env
とファイル名を変更したら読み込んでくれました。
ローカル環境のSupabase インストール
npm install @supabase/supabase-js @supabase/auth-helpers-nextjs react-icons
supabase init
supabase start
supabase status
Supabaseの環境変数
API URL: http://127.0.0.1:54321
GraphQL URL: http://127.0.0.1:54321/graphql/v1
S3 Storage URL: http://127.0.0.1:54321/storage/v1/s3
DB URL: postgresql://postgres:postgres@127.0.0.1:54322/postgres
Studio URL: http://127.0.0.1:54323
Inbucket URL: http://127.0.0.1:54324
JWT secret: super-secret-jwt-token-with-at-least-32-characters-long
anon key: ey*****I0
service_role key: ey*****U
S3 Access Key: 62*****3c
S3 Secret Key: 85*****07
S3 Region: local
Next.js アプリの環境変数
Next.js、GitHub認証の環境変数
GitHubの環境変数 GITHUB_CLIENT_ID と GITHUB_SECRET の取得方法は👇️を御覧ください。
Next.js + Supabase アプリでサーバーやローカル開発環境で、認証に必要な Client ID と Client secrets の取得。(Slack、Google、GitHub) #OAuth - Qiita
GitHub認証 ローカルで動かす OAuth-practice #localhost - Qiita
touch .env
.env
ファイルに以下を記述します。
# 環境変数
# Next.js 15
# Supabase ローカルローカル環境
GITHUB_REDIRECT_URI="http://127.0.0.1:54321/auth/v1/callback"
GITHUB_CLIENT_ID="Ox***"
GITHUB_SECRET="e3***"
NEXT_PUBLIC_SITE_URL="http://localhost:3000"
NEXT_PUBLIC_SUPABASE_URL="http://127.0.0.1:54321"
NEXT_PUBLIC_SUPABASE_ANON_KEY="ey***"
認証機能の実装: Supabase Authを用いた ソーシャルログイン (GitHub認証)
Next.js Supabase でのソーシャルログイン (Github認証) を作成します。
SupabaseでのGitHub認証の有効化
Supabaseの設定ファイルに追記します。
...
[auth.external.github]
enabled = true
client_id = "env(GITHUB_CLIENT_ID)"
secret = "env(GITHUB_SECRET)"
# Overrides the default auth redirectUrl.
redirect_uri = ""
Supabaseがエラーで起動しない場合
supabase_vector_[アプリ名] container is not ready: unhealthy エラー対処方法 Supabaseローカル開発環境 #Supabase - Qiita
...
[analytics]
enabled = false
port = 54327
# Configure one of the supported backends: `postgres`, `bigquery`.
backend = "postgres"
👆️設定ファイルの一部 [analytics] を無効化します。
Next.js での GitHub認証コードの実装
GitHub認証に必要な最低限のファイルツリー
./src
├── app
│ ├── auth
│ │ └── callback
│ │ └── route.ts
│ ├── layout.tsx
│ └── page.tsx
├── components
│ └── auth
│ └── social-login-buttons.tsx
└── lib
└── supabase.ts
./supabae
└── config.toml
supabaseフォルダは supabase init
コマンドで自動で出来ます。
src\app\layout.tsx
import './globals.css';
import type { Metadata } from 'next';
import { Inter } from 'next/font/google';
const inter = Inter({ subsets: ['latin'] });
export const metadata: Metadata = {
title: 'Create Next App',
description: 'Generated by create next app',
};
export default function RootLayout({
children,
}: {
children: React.ReactNode;
}) {
return (
<html lang="ja">
<body className={inter.className}>{children}</body>
</html>
);
}
src\app\page.tsx
import { SocialLoginButtons } from '@/components/auth/social-login-buttons';
export default function Home() {
return (
<div className="min-h-screen flex items-center justify-center bg-background">
<h1 className="text-2xl font-bold text-center text-foreground">
ソーシャルログイン
</h1>
<SocialLoginButtons />
</div>
);
}
src\components\auth\social-login-buttons.tsx
'use client';
import { supabase } from '@/lib/supabase';
import { FcGoogle } from 'react-icons/fc';
import { FaGithub } from 'react-icons/fa';
export function SocialLoginButtons() {
// 確認
console.log('SocialLoginButtons');
const handleGithubLogin = async () => {
// 確認
console.log('handleGithubLogin');
await supabase.auth.signInWithOAuth({
provider: 'github',
options: {
// サーバー側でのリダイレクトURLを指定
// redirectTo: `${window.location.origin}/auth/callback`,
// ローカル環境でのリダイレクトURLを指定
redirectTo: 'http://192.168.1.2:3000/auth/callback',
},
});
};
const handleGoogleLogin = async () => {
await supabase.auth.signInWithOAuth({
provider: 'google',
options: {
// サーバー側でのリダイレクトURLを指定
// redirectTo: `${window.location.origin}/auth/callback`,
// ローカル環境でのリダイレクトURLを指定
redirectTo: 'http://192.168.1.2:3000/auth/callback',
},
});
};
return (
<div className="flex flex-col gap-4 w-full max-w-sm">
<button
onClick={handleGithubLogin}
>
<FaGithub className="w-5 h-5" />
GitHubでログイン
</button>
<button
onClick={handleGoogleLogin}
>
<FcGoogle className="w-5 h-5" />
Googleでログイン
</button>
</div>
);
}
src\lib\supabase.ts
import { createClient } from '@supabase/supabase-js';
if (!process.env.NEXT_PUBLIC_SUPABASE_URL) {
throw new Error('Missing env.NEXT_PUBLIC_SUPABASE_URL');
}
if (!process.env.NEXT_PUBLIC_SUPABASE_ANON_KEY) {
throw new Error('Missing env.NEXT_PUBLIC_SUPABASE_ANON_KEY');
}
export const supabase = createClient(
process.env.NEXT_PUBLIC_SUPABASE_URL,
process.env.NEXT_PUBLIC_SUPABASE_ANON_KEY
);
src\app\auth\callback\route.ts
import { createRouteHandlerClient } from '@supabase/auth-helpers-nextjs';
import { cookies } from 'next/headers';
import { NextResponse } from 'next/server';
export async function GET(request: Request) {
const requestUrl = new URL(request.url);
const code = requestUrl.searchParams.get('code');
if (code) {
const supabase = createRouteHandlerClient({ cookies });
await supabase.auth.exchangeCodeForSession(code);
}
return NextResponse.redirect(new URL('/', requestUrl.origin));
}
以上でコードは終了です。
Next.jsを立ち上げ、
Supabaseを立ち上げ
ログインボタンを押せば、Supabaseのauth.usersテーブルにユーザーが登録されています。
Supabaseに登録したユーザーを見る方法
Table Editorから schema authを選択
usersテーブルを選択
SQL Editorから
SQL文を入力
ダッシュボードから Authentication
から見ることが出来ます。
Supabaseから認証済みユーザーデータの削除
これはシステムに登録されているので、削除手段が少ないです。
ダッシュボードから Authentication から削除できます。
AuthenticationでUsersテーブルの情報が見れます。
削除したいユーザーを選択すると、詳細な情報が見れます。
その下に削除ボタンがあるので押します。
その他
GitHub認証を応用して Google認証 等も追加できます。
ログインボタンだけは作ってあります。
GoogleからソーシャルログインのIDとSECRETを取得しておきます。
config.tomlに追記します。
...
[auth.external.google]
enabled = true
client_id = "env(GOOGLE_CLIENT_ID)"
secret = "env(GOOGLE_SECRET)"
# Overrides the default auth redirectUrl.
redirect_uri = ""
後はGitHubと似たような感じでコードを組み立てます。
最後に
Blot.newを使うと1行のプロンプトで Next.jsとSupabaseのGitHub認証コードが出ます。
Blot.newでの出力時にエラーが出るのは .envファイルを自分で書く必要があるからです。
自分が昔GitHub認証のコードを調べたときは1週間ぐらいやった気がしましたが、今では1行で終わりです。
中身を知らないままコードを書いていっても危険だと思い、ちょっと調べてみました。
認証は Supabaseの SSR
ではなく @supabase/auth-helpers-nextjs
を使っていました。
この記事を利用してDrizzleを使う記事を書く予定です。