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

1. 概要

前回はOauthを使いGoogleアカウントでログインする内容についてでした。今回はOauthやAWS Cognitoを使いGoogleアカウントでログインする内容になります。

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

2. nodeのインストール

こちらを参考

3. プロジェクトを作成

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

3-2-1. GoogleAPIを設定

https://<your-user-pool-domain>/oauth2/idpresponse

3-3-1. AWS Cognitoを設定

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

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

5. ソースコード

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

5-1-1. .env.local

NEXTAUTH_SECRET=******
COGNITO_CLIENT_ID=******
COGNITO_CLIENT_SECRET=******
COGNITO_ISSUER=******

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

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

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

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

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

export const {
  handlers: { GET, POST },
  auth,
  signIn,
  signOut,
} = NextAuth({
  ...authConfig,
  providers: [
    congnito({
      clientId: process.env.COGNITO_CLIENT_ID,
      clientSecret: process.env.COGNITO_CLIENT_SECRET,
      issuer: process.env.COGNITO_ISSUER,
      checks: ["nonce"],
    }),
  ],
});

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

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

5-1-5. src/app/nextjs/nextjs08/loginActions.ts

"use server";

import { AuthError } from "next-auth";
import { signIn } from "./auth";

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

5-1-6. src/app/nextjs/nextjs08/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/nextjs08/page.module.scss

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

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

"use client";

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

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

  const [errorMsgCognito, dispatchCognito] = useFormState(
    congnitoAuthenticate,
    undefined
  );

  return (
    <div className={scss.component}>
      <GoBack />
      <br />
      <br />
      {status != "authenticated" ? (
        <ul>
          <li>Google Sign in with Cognito</li>
          <ul>
            <li>
              <form className="flex flex-col" action={dispatchCognito}>
                <Button
                  type="submit"
                  variant="contained"
                  size="small"
                  color="primary"
                >
                  Google Sign in with Cognito
                </Button>
                <p>{errorMsgCognito}</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/nextjs08/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>
        <li>
          <Link href="/nextjs/nextjs08" underline="hover">
            Nextjs08
          </Link>
        </li>
      </ul>
    </div>
  );
};

export default Nextjs;

6. サーバーを起動

npm run dev

7. ブラウザで確認

  • http://localhost:3000

8. ディレクトリの構造

省略

9. 備考

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

10. 参考

投稿者プロフィール

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

関連記事

  1. 【NextJS】TextField

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

  3. 【NextJS】SnackbarやLink

  4. 【NextJS】Hooks-useState(update separ…

  5. 【NextJS】Server Actions with MySQL

  6. 【NextJS】Firestore

最近の記事

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

制作実績一覧

  1. Checkeys