【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. 参考

関連記事

  1. 【NextJS】AWS SAMを使いCLIでデプロイしたLambda関…

  2. 【NextJS】Metadata(Head,Title)・Script…

  3. 【NextJS】FullCalendar

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

  5. 【NextJS】Hooks-useEffect

  6. 【NextJS】Hooks-useContext・useReducer…

最近の記事

  1. AWS
  2. AWS
  3. AWS
  4. AWS
  5. AWS
  6. AWS
  7. AWS
  8. AWS

制作実績一覧

  1. Checkeys