🙄

Next.js Supabase Prisma を使用してアプリを作る 5/6 覚書

2022/06/28に公開

https://themodern.dev/learn/courses/322389284337222224?l=323674267365409360

認証機能を追加

  • OAuth
    クライアント → アクセストークン要求 → Twitter等の認可サーバー → トークン生成していいかユーザーに聞く → OK → トークン生成 → クライアント
    みたいな流れ。

概要

OAuth を使用した認証と PrismaAdapterfor を使用したセッション永続化をしていく

NextAuth を設定

  • マジックリング認証

    • メール内に記載されたリンクを踏むことで認証が完了するやつ
  • next-auth をインストール
    npm install --save next-auth

  • インポート

import '../styles/globals.css';
import { Toaster } from 'react-hot-toast';
// as は別名にしたいとき.
import { SessionProvider as AuthProvider } from "next-auth/react";

function MyApp({ Component, pageProps: { session, ...pageProps } }) {
  return (
    <>
      <AuthProvider session={session}>
        <Component {...pageProps} />
      </AuthProvider>
      <Toaster />
    </>
  );
}

export default MyApp;

こんだけやったけど SMTP の設定がうまく行かず後のグーグル認証だけ使うことに。

Prisma アダプター

セッションの永続化

NextAuth ↔ prisma ↔ Supabase

npm install faunadb @next-auth/prisma-adapter

[...nextauth].js にインポート

import { PrismaAdapter } from '@next-auth/prisma-adapter';
import { PrismaClient } from '@prisma/client';

// プリズマクライアントインスタンス化.
const prisma = new PrismaClient();

アダプターをNextAuth構成オブジェクトに追加

export default NextAuth({
  providers: [...],
  adapter: PrismaAdapter(prisma),
});

Prisma スキーマ更新

DB 設計はまだよくわからないので後で確認

秘密鍵生成

open rand -base64 32

ログアウト

現在のセッション情報を取得しログアウトできるようにする。
NextAuth は useSession を提供している

const {data: session, status } = useSession();
const user = session?.user;
const isLoadingUser = status === 'loading';

status が持つ3つの状態

  • loading
  • authenticated
  • unauthenticated

を材料に条件分岐する。

サインアウト機能.

import { useSession, signOut } from 'next-auth/react';
const menuItems = [
  //..
  {
    label: 'Logout',
    icon: LogoutIcon,
    // NextAuth の signOut メソッドを呼び出せばOK.
    onClick: signOut,
  },
];

カスタム React コンポーネントを使用してサインイン

NextAuth の設定を変更すればログインの設定を変更できる。

js
export default NextAuth({
  pages: {
    signIn: '/',
    signOut: '/',
    error: '/',
    verifyRequest: '/',
  },
  //...
}

サインインをクリックしたときに AuthModal コンポーネントを呼び出す。

import { signIn } from 'next-auth/react';
const AuthModal = ({ show = false, onClose = () => null }) => {
  const signInWithGoogle = () => {
    toast.loading('Redirecting...');
    setDisabled(true);
    signIn('google', {
      callbackUrl: window.location.href,
    });
  };
}

Discussion