2
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 1 year has passed since last update.

【Next.js】NextAuth.jsでのログイン・ログアウト(Github、Google)

2
Last updated at Posted at 2025-05-10

記事のきっかけ

  • UdemyのNext.js講座でNextAuthを学んだ際の振り返りで理解を深めるため。

NextAuth.jsとは

  • NextAuth.jsは、Next.jsアプリケーションに
    簡単に認証機能を追加できるライブラリです。
    ログインやサインアップ、ユーザー管理などの複雑な認証処理を
    少ないコードで実装できます。

NextAuth.jsの主な特徴

  1. 簡単セットアップ: 数行のコードだけで認証システムを導入できます
  2. 多様なログイン方法: メール/パスワードだけでなく、
    GoogleやGitHubなどのSNSログインも簡単に設定できます
  3. セキュリティ対策済み: セキュリティの専門知識がなくても、
    安全な認証システムが構築できます
  4. データベース不要: シンプルな認証ならデータベースなしでも使えます

  • 現在、NextAuthの進化版としてAuth.jsがありますが、
    講座ではNextAuthを使用していたのと、
    Auth.jsの最新版がBetaとなっていて不安だったので、
    講座の通り、NextAuthを使用しました。

開発環境

パッケージ名 バージョン
Next.js 15.3.1
NextAuth 4.24.11
React 19.0.0

環境構築

1. Next.jsプロジェクト作成

npx create-next-app@latest

2. 作成したプロジェクトのディレクトリ移動後、

NextAuthをインストール
npm install next-auth

3. opnesslをインストール・秘密鍵作成

brew install openssl
※homebrewをインストールしていない方はインストールをお願いします。
openssl rand -base64 32

4.Github側の準備(アプリケーション作成)

  • GitHubにログインし、右上のプロフィールアイコン→「Settings」をクリック
    左サイドバーから「Developer settings」を選択
  • 「OAuth Apps」をクリック
  • 「New OAuth App」ボタンをクリック
  • 以下の情報を入力:
    Application name: Book Commerce App(あなたのアプリ名)
    Homepage URL: http://localhost:3000(開発環境)
    Application description: 任意の説明
    Authorization callback URL: http://localhost:3000/api/auth/callback/github
  • 「Register application」をクリック
  • 作成後、「Generate a new client secret」をクリックして、
    Client Secretを発行
  • Client IDとClient Secretをメモしておく(環境変数として使用)

5.Github側の準備(Google Cloud Platform設定)

  • Google Cloud Console にアクセス・ログイン
  • 画面上部の「プロジェクトを選択」→「新しいプロジェクト」をクリック
  • プロジェクト名を入力し「作成」をクリック
  • 左サイドメニューから「APIとサービス」→「認証情報」を選択
  • 「認証情報を作成」→「OAuth クライアントID」をクリック
  • 「同意画面を構成」をクリック
    User Type: 外部を選択
    必要な情報(アプリ名、メールアドレスなど)を入力
    スコープは基本的なものだけ選択
    テストユーザーに自分のメールアドレスを追加
  • 「認証情報を作成」→「OAuth クライアントID」を再度クリック
    以下の情報を入力:
    アプリケーションの種類: ウェブアプリケーション
    名前: 自分のアプリ名
    承認済みのリダイレクトURI: http://localhost:3000/api/auth/callback/google
  • 「作成」をクリック
  • クライアントIDとクライアントシークレットをメモしておく

実装例

■環境変数(.env)

.env
NEXTAUTH_SECRET=opensslの秘密鍵
GITHUB_ID=GithubのアプリID
GITHUB_SECRET=Githubのシークレットキー

GOOGLE_CLIENT_ID=GoogleのクライアントID
GOOGLE_CLIENT_SECRET=Githubのシークレットキー

■NextAuthの認証設定

app/lib/next-auth/option.ts
import { NextAuthOptions } from "next-auth"
import GithubProvider from "next-auth/providers/github"
import GoogleProvider from "next-auth/providers/google"

export const nextAuthOptions: NextAuthOptions = {
    debug: false,
    providers: [
        GithubProvider({
            clientId: process.env.GITHUB_ID!,
            clientSecret: process.env.GITHUB_SECRET!
        }),
        GoogleProvider({
            clientId: process.env.GOOGLE_CLIENT_ID!,
            clientSecret: process.env.GOOGLE_CLIENT_SECRET!
        })
    ],
    callbacks: {
        session: ({ session, token, user }) => {
            return {
                ...session,
                ...token,
                user: {
                    ...session.user,
                    ...token,
                    id: user.id
                }
            }
        }
    },
    secret: process.env.NEXTAUTH_SECRET
}

■認証情報の共有設定

app/lib/next-auth/provider.tsx
"use client"

import { SessionProvider } from "next-auth/react"
import { FC, PropsWithChildren } from "react"

export const NextAuthProvider: FC<PropsWithChildren> = ({ children }) => {
    return <SessionProvider>{children}</SessionProvider>
}
app/layout.tsx
import type { Metadata } from "next"
import { Noto_Sans_JP } from "next/font/google"
import "./globals.css"
import { NextAuthProvider } from "./lib/next-auth/provider";

export default function RootLayout({
  children,
}: Readonly<{
  children: React.ReactNode;
}>) {
  return (
    <html lang="ja">
      <body
        className={`${notoSansJP.variable} antialiased`}
      >
        <NextAuthProvider>
            {children}
        </NextAuthProvider>
      </body>
    </html>
  );
}

■ログイン認証APIルート設定
※[...nextauth]はNext.jsの「API Route」機能を使う際に必要です。

app/api/[...nextauth]/route.ts
import { nextAuthOptions } from "@/app/lib/next-auth/options";
import NextAuth from "next-auth";

const handler = NextAuth(nextAuthOptions)

export { handler as GET, handler as POST }

■ログイン画面へ遷移するためのリンク設定
※href指定の「"/api/auth/signin"」は
 NextAuthで用意されている標準サインイン画面に遷移します。

app/sample/page.tsx
import Link from "next/link"

// 〜ソース抜粋〜
<Link
    href={"/api/auth/signin"}   // Next-Authが用意したログインの標準API
    className="text-gray-300 hover:text-white px-3 py-2 rounded-md text-sm font-medium"
>
    ログイン
</Link>

■ログアウト画面へ遷移するためのリンク設定

app/sample/page.tsx
import Link from "next/link"

// 〜ソース抜粋〜
<Link
    href={"/api/auth/signout"}   // Next-Authが用意したログアウトの標準API
    className="text-gray-300 hover:text-white px-3 py-2 rounded-md text-sm font-medium"
>
    ログアウト
</Link>

■ログイン画面
スクリーンショット 2025-05-10 13.21.55.png

■ログアウト画面
スクリーンショット 2025-05-10 13.24.06.png

おまけ(プロフィール画像)

Githubやgoogleのプロフィール画像を表示する場合は、
next.config.tsでドメイン指定が必要になります。
※指定しないとエラーが発生します。

next.config.ts
import type { NextConfig } from "next";

const nextConfig: NextConfig = {
  /* config options here */
  images: {
    domains: [
      "avatars.githubusercontent.com",  // Githubのプロフィール画像
      "lh3.googleusercontent.com"  // Googleのプロフィール画像
    ]
  }
};

export default nextConfig;

プロフィール画像表示画面(ヘッダー用コンポーネント)

app/components/Header.tsx
import { getServerSession } from "next-auth"
import Image from "next/image"
import Link from "next/link"
import { nextAuthOptions } from "../lib/next-auth/options"

const Header = async () => {

    const session = await getServerSession(nextAuthOptions)
    const user = session?.user

    return (
        <header className="bg-slate-700 text-gray-100 shadow-lg">
            <nav className="flex items-center justify-between p-4">
                <div className="flex items-center gap-2">
                    <Link href={"/profile"}>
                        <Image
                            width={50}
                            height={50}
                            alt="profile_icon"
                            src={user?.image || "/default_icon.png"}
                            className="rounded-full"
                        />
                    </Link>
                </div>
            </nav>
        </header>
    )
}

export default Header

ログイン前

スクリーンショット 2025-05-10 19.24.02.png

ログイン後(画像はGithubのプロフィール画像です)

スクリーンショット 2025-05-10 19.30.50.png

まとめ

X(旧Twitter)とFacebookも挑戦したのですが、
Facebookは本番環境ではエラーで解決できず、
Xは認証自体お金がかかりそうだったので、一旦諦めました。
やり方がわかる方いらっしゃいましたら、コメントいただけると嬉しいです。

今度はリファクタリングでAuth.jsを使っての認証を試してみたいです。

2
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
2
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?