Closed11

Next.jsでSupabaseを使ってGitHub認証をする

hirotakahirotaka

TypescriptをベースにNext.jsプロジェクトを作成します。

npx create-next-app --typescript --use-npm supabase-nextjs-chat
cd supabase-nextjs-chat
npm install --save-dev typescript @types/react
touch tsconfig.json

いつもの手順をします。
https://zenn.dev/hrtk/scraps/d379315607e5c9

Supabaseクライアントをインストールします。

npm install @supabase/supabase-js

起動します。

npm run dev
hirotakahirotaka

クライアントIDとシークレット生成

GitHubでこちらから新しくアプリケーションを作成します。

  • Application name
    アプリケーションの名称を入力します。
  • Homepage URL
    ホームページのURLを入力します。
  • Authorization callback URL
    Supabaseのダッシュボードから、プロジェクトのサイドメニューの「Settings」を選んで、「API」の「Config」欄にURLがあるので、そのURLに/auth/v1/callbackを追加して入力します。

「Register application」ボタンをクリックして、アプリケーションを作成します。

作成後、アプリケーションの設定画面が開くので、「Client secrets」欄に「Genrate a new client secret」ボタンをクリックして、シークレットを生成します。

「Client ID」と「Client secrets」を保持しておきます。

hirotakahirotaka

SupabaseのAuthenticationを設定

サイドメニューの「Authentication」を選んで、「Settings」を選択します。

「External OAuth Providers」欄の「GitHub enabled」のトグルをオンにします。

そうすると、「GitHub client ID」と「GitHub secret」のテキスト入力欄が表示されるので、先ほど保持したGitHubの「Client ID」と「Client secrets」をそれぞれに入力します。「Save」ボタンをクリックして、設定を保存します。

hirotakahirotaka

「Settings」から「API」を選択します。

URLとパブリックキーを控えます。

.env.localというファイルを作成して、NEXT_PUBLIC_SUPABASE_ANON_KEYにパブリックキー、NEXT_PUBLIC_SUPABASE_URLにURLをセットします。

NEXT_PUBLIC_SUPABASE_ANON_KEY=xxxxxxxxxxxxxxxxxxxxxx
NEXT_PUBLIC_SUPABASE_URL=https://xxxxxxxxxxxxx.supabase.co
hirotakahirotaka

Supabaseクライアントを初期化するファイルを作成します。

lib/supabase-client.ts
import { createClient } from '@supabase/supabase-js'

const supabaseUrl = process.env.NEXT_PUBLIC_SUPABASE_URL
const supabaseAnonKey = process.env.NEXT_PUBLIC_SUPABASE_ANON_KEY

export const supabase = createClient(supabaseUrl, supabaseAnonKey)
hirotakahirotaka
pages/index.tsx
import { useEffect, useState } from 'react'
import { supabase } from '../lib/supabase-client'

export default function Home() {
  const [session, setSession] = useState()

  useEffect(() => {
    const { data: authListener } = supabase.auth.onAuthStateChange(
      (event, session) => {
        setSession(session)
      }
    )

    return () => {
      authListener.unsubscribe()
    }
  }, [])

  function signInWithGithub() {
    supabase.auth.signIn({ provider: 'github' })
  }

  function signOut() {
    supabase.auth.signOut()
  }

  return (
    <>
      {session ? (
        <button onClick={() => signOut()}>サインアウト</button>
      ) : (
        <button onClick={() => signInWithGithub()}>GitHubでログイン</button>
      )}
    </>
  )
}
hirotakahirotaka

usesテーブルを作成する。

create table users (
  id uuid references auth.users not null primary key,
  full_name text,
  avatar_url text,
  nickname text
);
alter table users enable row level security;
create policy "Can view own user data." on users for select using (auth.uid() = id);
create policy "Can update own user data." on users for update using (auth.uid() = id);

/**
* Supabase Authでサインアップしたら自動でユーザを作成するためのトリガー
*/
create function public.handle_new_user()
returns trigger as $$
begin
  insert into public.users (id, full_name, avatar_url)
  values (new.id, new.raw_user_meta_data->>'full_name', new.raw_user_meta_data->>'avatar_url');
  return new;
end;
$$ language plpgsql security definer;
create trigger on_auth_user_created
  after insert on auth.users
  for each row execute procedure public.handle_new_user();

「SQL」をサイドメニューから開いて、「Open queries」の「Query-1」を開くと、クエリーエディターが開くので、SQLを入力して、「RUN」をクリックしてSQLを実行します。

hirotakahirotaka

「GitHubでログイン」をクリックすると、GitHub側の認証処理が実行されます。

GitHubアプリケーションでのログインを許可するかどうか確認されるので、「Authorize xxx」(xxxはそれぞれのGitHubユーザや組織名がはいります)ボタンをクリックします。

hirotakahirotaka

これで、Supabaseでも認証処理が実行され、ユーザが作成されます。

「Authentication」の「Users」で確認します。

先ほど作成したトリガーでusersテーブルにもレコードが作成されます。

このスクラップは2021/09/28にクローズされました