🙄
Next.js Supabase Prisma を使用してアプリを作る 5/6 覚書
認証機能を追加
- 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;
-
SessionProvider
- https://next-auth.js.org/getting-started/client#usesession
- 内部的に ReactContext を使用して useSession() のインスタンスで、コンポーネント間でセッションオブジェクトを共通できる。
- タブやウィンドウ間でセッションの更新や同期を維持できる。
-
nodemailer をインストール
npm i nodemailer
-
EmailProvider でマジックリングを設定
-
SMTP サーバーはグーグル
https://kinsta.com/jp/blog/gmail-smtp-server/
こんだけやったけど 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