【NextJS】OAuth authentication with Google account(Auth.js)

1. 概要

前回はNextJSで開発されたPankoの利用シーンについてでした。今回はOauthを使いGoogleアカウントでログインする内容になります。

対象としては開発を1年程やってて自分で最初から開発してみたい方になります。そのため細かい用語などの説明はしません。

2. nodeのインストール

こちらを参考

3. プロジェクトを作成

3-1-1. こちらを参考

3-2-1. GoogleAPIを設定

4. 必要なライブラリをインストール

4-1-1. こちらを参考

npm install next-auth@beta

5. ソースコード

※前回より差分のみを記載

5-1-1. .env.local

NEXTAUTH_SECRET=******
GOOGLE_CLIENT_ID=******
GOOGLE_CLIENT_SECRET=******

5-1-2. src/app/nextjs/nextjs07/auth.config.ts

import google from "next-auth/providers/google";
import type { NextAuthConfig } from "next-auth";

export const authConfig = {
  providers: [google],
  pages: {},
  callbacks: {},
} satisfies NextAuthConfig;

5-1-3. src/app/nextjs/nextjs07/auth.ts

import NextAuth from "next-auth";
import google from "next-auth/providers/google";
import { authConfig } from "@/app/nextjs/nextjs07/auth.config";

export const {
  handlers: { GET, POST },
  auth,
  signIn,
  signOut,
} = NextAuth({
  ...authConfig,
  providers: [
    google({
      clientId: process.env.GOOGLE_CLIENT_ID,
      clientSecret: process.env.GOOGLE_CLIENT_SECRET,
    }),
  ],
});

5-1-4. src/app/api/auth/[…nextauth]/route.ts

export { GET, POST } from "@/app/nextjs/nextjs07/auth";

5-1-5. src/lib/components/loginActions.ts

"use server";

import { signIn } from "@/app/nextjs/nextjs07/auth";
import { AuthError } from "next-auth";

export const googleAuthenticate = async (
  prevState: string | undefined,
  formData: FormData
) => {
  try {
    await signIn("google");
  } catch (error) {
    if (error instanceof AuthError) {
      return "Failed";
    }
    throw error;
  }
};

5-1-6. src/app/nextjs/nextjs07/auth-provider.tsx

import { SessionProvider } from "next-auth/react";
import { ReactNode } from "react";

const AuthProvider = ({ children }: { children: ReactNode }) => {
  return <SessionProvider>{children}</SessionProvider>;
};

export default AuthProvider;

5-1-7. src/app/nextjs/nextjs07/page.module.scss

.component {
  color: blue;
  & ul {
    margin-left: 20px;
    & li {
      list-style: disc;
    }
  }
}

5-1-8. src/app/nextjs/nextjs07/login.tsx

"use client";

import scss from "./page.module.scss";
import GoBack from "@/lib/components/go-back";
import { Button } from "@mui/material";
import { googleAuthenticate } from "@/lib/components/loginActions";
import { useFormState } from "react-dom";
import { useSession, signOut } from "next-auth/react";

const Login = () => {
  const { data: session, status } = useSession({ required: false });

  const [errorMsgGoogle, dispatchGoogle] = useFormState(
    googleAuthenticate,
    undefined
  );

  return (
    <div className={scss.component}>
      <GoBack />
      <br />
      <br />
      {status != "authenticated" ? (
        <ul>
          <li>Login with Google</li>
          <ul>
            <li>
              <form className="flex flex-col" action={dispatchGoogle}>
                <Button
                  type="submit"
                  variant="contained"
                  size="small"
                  color="primary"
                >
                  Google Sign In
                </Button>
                <p>{errorMsgGoogle}</p>
              </form>
            </li>
          </ul>
        </ul>
      ) : (
        <ul>
          <li>You are signed as below</li>
          <ul>
            <li>Your name</li>
            <ul>
              <li>{session.user?.name}</li>
            </ul>
            <li>Your email</li>
            <ul>
              <li>{session.user?.email}</li>
            </ul>
          </ul>
          <li>
            <Button
              variant="contained"
              size="small"
              color="primary"
              onClick={() => signOut()}
            >
              Google Sign Out
            </Button>
          </li>
        </ul>
      )}
      <br />
    </div>
  );
};

export default Login;

5-1-9. src/app/nextjs/nextjs07/page.tsx

import AuthProvider from "./auth-provider";
import Login from "./login";

const Nextjs07 = () => {
  return (
    <AuthProvider>
      <Login />
    </AuthProvider>
  );
};

export default Nextjs07;

5-1-10. src/app/nextjs/page.tsx

"use client";

import React from "react";
import { Link } from "@mui/material";
import scss from "./page.module.scss";

const Nextjs = () => {
  return (
    <div className={scss.components}>
      <ul>
        <li>
          <Link href="/nextjs/nextjs01" underline="hover">
            Nextjs01
          </Link>
        </li>
        <li>
          <Link href="/nextjs/nextjs02" underline="hover">
            Nextjs02
          </Link>
        </li>
        <li>
          <Link href="/nextjs/nextjs03" underline="hover">
            Nextjs03
          </Link>
        </li>
        <li>
          <Link href="/nextjs/nextjs04" underline="hover">
            Nextjs04
          </Link>
        </li>
        <li>
          <Link href="/nextjs/nextjs05" underline="hover">
            Nextjs05
          </Link>
        </li>
        <li>
          <Link href="/nextjs/nextjs06" underline="hover">
            Nextjs06
          </Link>
        </li>
        <li>
          <Link href="/nextjs/nextjs07" underline="hover">
            Nextjs07
          </Link>
        </li>
      </ul>
    </div>
  );
};

export default Nextjs;

6. サーバーを起動

npm run dev

7. ブラウザで確認

  • http://localhost:3000

8. ディレクトリの構造

省略

9. 備考

今回はOauthを使いGoogleアカウントでログインする内容についてでした。

10. 参考

投稿者プロフィール

Sondon
開発好きなシステムエンジニアです。
卓球にハマってます。

関連記事

  1. 【NextJS】Firestore

  2. 【NextJS】SassとTypescriptでレイアウトを構成

  3. 【NextJS】Streaming with Suspense

  4. 【NextJS】Events

  5. 【NextJS】OAuth authentication with A…

  6. 【NextJS】Canvasを使い、図形を描画

最近の記事

  1. AWS
  2. AWS
  3. AWS
  4. AWS
  5. AWS

制作実績一覧

  1. Checkeys