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

関連記事

  1. 【NextJS】Events

  2. 【NextJS】Hooks-useContext・useReducer…

  3. 【NextJS】Server Actions with MySQL

  4. 【NextJS】Firestore

  5. 【NextJS】Redux

  6. 【NextJS】OAuth authentication with G…

最近の記事

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

制作実績一覧

  1. Checkeys