【Next.js 13】NextAuth+FireStoreにユーザー情報を保存する。
2023/7/12
2023/7/12
今回は、以下の3つをNext.js 13で実装するためのメモです。
- Googleアカウントでログインできる
- アカウント、セッション情報をFirestoreに保存する
- サーバーサイドとクライアントサイドからセッション情報を取得できる
目次
0)パッケージをインストール
$ npm install next-auth
$ npm install firebase-admin
$ npm install @next-auth/firebase-adapter
1)GCP & Firebaseのプロジェクトを作成する
「Google Cloud Platform」のプロジェクトを作成する
※今回は省略します。(手順は下記記事でメモしています。)
「Firebase」のプロジェクトを作成する
※今回は省略します。(手順は下記記事でメモしています。)
2)NextAuthに必要なファイルを作る
- app/api/auth/[…nextauth]/route.ts
- lib/options.ts
import { authOptions } from "@/lib/options";
import NextAuth from "next-auth";
const handler = NextAuth(authOptions);
export {handler as GET,handler as POST}
import NextAuth, {Session, User} from "next-auth"
import GoogleProvider from 'next-auth/providers/google';
import { FirestoreAdapter } from "@next-auth/firebase-adapter"
import { JWT } from "next-auth/jwt/types";
import { cert } from "firebase-admin/app";
export const authOptions = {
providers: [
GoogleProvider({
clientId: process.env.GOOGLE_CLIENT_ID ?? "",
clientSecret: process.env.GOOGLE_CLIENT_SECRET ?? "",
}),
],
adapter: FirestoreAdapter({
credential: cert({
projectId: process.env.FIREBASE_PROJECT_ID,
clientEmail: process.env.FIREBASE_CLIENT_EMAIL,
privateKey: process.env.FIREBASE_PRIVATE_KEY?.replace(/\\n/gm, "\n"),
}),
}),
secret: process.env.NEXTAUTH_SECRET,
// debug: true,
}
export default NextAuth(authOptions)
環境変数に必要な情報を追加する
FIREBASE_PROJECT_ID=
FIREBASE_PRIVATE_KEY=
FIREBASE_CLIENT_EMAIL=
GOOGLE_CLIENT_ID=
GOOGLE_CLIENT_SECRET=
NEXTAUTH_SECRET=
※「NEXTAUTH_SECRET」には$ openssl rand -base64 32
で生成したランダムな文字列を設定すればOK。
3)ログイン情報の取得方法
「サーバーサイド」から取得する
import { getServerSession } from "next-auth";
import { authOptions } from "../lib/authOptions";
export default async function Home() {
const session = await getServerSession(authOptions); // セッション情報を取得
return (
<>
{ session &&
<div>...</div>
}
</>
);
}
「クライアントサイド」から取得する
クライアントサイドからセッション情報を取得するには、SessionProvider
で囲う必要があります。
"use client";
import { SessionProvider } from "next-auth/react";
export const NextAuthProvider = ({ children }: {children?: React.ReactNode}) => {
return <SessionProvider>{children}</SessionProvider>;
};
import { NextAuthProvider } from "@/components/NextAuthProvider";
export default function RootLayout({children,}: {children: React.ReactNode;}) {
return (
<NextAuthProvider>
<html lang="ja">
<body>{chidren}</body>
</html>
</NextAuthProvider>
);
}
'use client';
import React from "react";
import {useSession} from "next-auth/react";
export default function EditButton() {
const { data: session, status } = useSession(); // セッション情報を取得
return (
<>
{status === "loading"
? // 0)読み込み中
<div>Loading...</div>
: status === "authenticated"
? // 1)ログイン済み
<div>Welcome, {session.user.name}!</div>
: // 2)未ログイン
<div>ログインしてください。</div>
}
</>
)
}
おまけ)権限ごとに表示コンテンツを分ける
Firestoreのセッション情報に管理権限のデータがある場合、それを使って権限ごとに表示コンテンツを分けるような処理ができました。
import NextAuth, {Session, User} from "next-auth"
import GoogleProvider from 'next-auth/providers/google';
import { FirestoreAdapter } from "@next-auth/firebase-adapter"
import { JWT } from "next-auth/jwt/types";
import { cert } from "firebase-admin/app";
export const authOptions = {
providers: [
GoogleProvider({
clientId: process.env.GOOGLE_CLIENT_ID ?? "",
clientSecret: process.env.GOOGLE_CLIENT_SECRET ?? "",
}),
],
adapter: FirestoreAdapter({
credential: cert({
projectId: process.env.FIREBASE_PROJECT_ID,
clientEmail: process.env.FIREBASE_CLIENT_EMAIL,
privateKey: process.env.FIREBASE_PRIVATE_KEY?.replace(/\\n/gm, "\n"),
}),
}),
secret: process.env.NEXTAUTH_SECRET,
callbacks: {
session({ session, token, user }: { session: Session, token: JWT, user: User }) {
session.user_id = user.id // ユーザーIDをセッション情報に追加
session.user_role = user.role // ユーザー権限をセッション情報に追加
return session
}
},
// debug: true,
}
export default NextAuth(authOptions)
export default async function Home() {
const session = await getServerSession(authOptions);
return (
<>
{ session?.user_role === "Administrator"
? <div>管理者だけ見れています</div>
: <div>閲覧権限がありません</div>
}
</>
);
}
まとめ
細かい部分で理解できていないところはありますが、一応動くところまでは今回のコードでできました!
最近の記事
音楽生成AI「Suno」の使い方まとめ!作詞作曲が簡単にできる?
簡単に曲が作れるAIということでよく聞く「Suno(Chirp)」についてまとめました。
目次「Suno」とはテキストからさまざまな音声を生成する「Bark」歌詞から曲を生成する「Chirp」...
2023/11/24
2023/11/24
【Open AI】APIの料金まとめ|GPT・DALL·E・Whisperなど
Open AIのAPI(一部)の料金をまとめました。
参考のために日本円は「1ドル150円」で換算をしています。
目次Text generation: テキスト生成Assistants ...
2023/11/22
2023/11/22
【Next.js】Assistants APIの基本的なコードまとめ。
Open AIの「Assistants API」をNext.jsで使用する時の基本的なコードをまとめました。
目次Open AIのAPIセットアップ基本の使い方Threads: スレッドを作る...
2023/11/21
2023/11/21
【Next.js】Open AIのAPIでファイルをアップロードする方法。
今回は、Next.jsサイトからOpen AIのAPI(Upload file)で、ファイルをアップロードする方法を実装するのに時間がかかったのでその過程と最終コードをまとめます。(Vercelにデ...
2023/11/21
2023/11/22
「生成系AIのWEBプロダクトTOP50」をまとめてみる。
Andreessen Horowitzが出している記事で紹介されている「AIプロダクトの月間訪問者数ランキングTOP50」のサービスをまとめました。
目次ChatGPTcharacter.ai...
2023/10/3
2023/10/3
【Next.js 13】NextAuth+FireStoreにユーザー情報を保存する。
今回は、以下の3つをNext.js 13で実装するためのメモです。
Googleアカウントでログインできる
アカウント、セッション情報をFirestoreに保存する
サーバーサイ...
2023/7/12
2023/7/12