"next" : "15.1.7" ,
"next-auth" : "^5.0.0-beta.25" ,
"react" : "^19.0.0" ,
"react-dom" : "^19.0.0"
App routerを使っていきます.
$ npx create-next-app@latest
✔ What is your project named? … frontend
✔ Would you like to use TypeScript? … Yes
✔ Would you like to use ESLint? … Yes
✔ Would you like to use Tailwind CSS? … Yes
✔ Would you like your code inside a `src/` directory? … No
✔ Would you like to use App Router? (recommended) … Yes
✔ Would you like to use Turbopack for `next dev`? … Yes
✔ Would you like to customize the import alias (`@/*` by default)? … No
公式サイトのやり方に則ります.
Auth.js | Installation
npm install next-auth@beta
ライブラリがトークンやメール認証用のハッシュを暗号化するために使用するランダムな値を生成し,自動で.env
あるいは.env.local
に保存されます.
$ npx auth secret
📝 Created [プロジェクトの場所].env.local with `AUTH_SECRET`.
ここでは使用したい認証プロバイダの指定やコールバックの設定などができます.ここでは単純にgoogleのプロバイダのみを使用します.
import NextAuth from "next-auth" ;
import Google from "next-auth/providers/google" ;
export const { handlers, signIn, signOut, auth } = NextAuth ({
providers : [Google ],
});
今後セッション管理用の関数を使うために,あらかじめルーティングを設定する必要があります.
import { handlers } from "@/auth" ;
export const { GET , POST } = handlers;
これを設定すると以下のエンドポイントが自動で作成されます
/api/auth/signin
(サインイン)
/api/auth/signout
(サインアウト)
/api/auth/session
(セッション情報取得)
/api/auth/callback/:provider
(OAuth コールバック)
/api/auth/csrf
(CSRF トークン取得)
これらが作成されることにより適切にAuth.jsが用意した関数を使用することができるようになります.
Google Cloudからプロジェクトを作成し,クライアントIDとシークレットキーを取得する必要があります
https://console.cloud.google.com/
ナビゲーションメニュー > APIとサービス > 認証情報
に移動し,認証情報を作成
します.種類は OAuth クライアント ID を選択してください.
OAuth クライアント ID の作成は以下のように設定してください.
アプリケーションの種類 ... ウェブアプリケーション
名前 ... 任意の名前
承認済みの JavaScript 生成元 ... http://localhost:3000
承認済みのリダイレクト URI ... http://localhost:3000/api/auth/callback/google
Tip
同意画面を作成していない場合は,事前に作成することを促されます.また作成後,サイトを再読み込みする必要があります.
OAuth クライアント IDの作成がうまくいくと,クライアント ID とクライアントシークレットを取得できます.これらを.env.local
に追加しておきます.
AUTH_GOOGLE_ID={CLIENT_ID}
AUTH_GOOGLE_SECRET={CLIENT_SECRET}
今回は,サインインしたのちに/dashboard
にリダイレクトするようにします.
import { signIn } from "@/auth" ;
export default function SignIn ( ) {
return (
<form
action ={async () => {
"use server";
await signIn("google", { redirectTo: "/dashboard" });
}}
>
<button
type ="submit"
className ="w-full bg-blue-500 text-white py-2 px-4 rounded hover:bg-blue-600"
>
Sign in with Google
</button >
</form >
);
}
import { signOut } from "@/auth" ;
export function SignOut ( ) {
return (
<form
action ={async () => {
"use server";
await signOut({ redirectTo: "/" });
}}
>
<button
type ="submit"
className ="w-full bg-red-500 text-white py-2 px-4 rounded hover:bg-red-600"
>
Sign Out
</button >
</form >
);
}
/dashboard
以下の階層ではログインしないと入れないような仕組みにします.auth()
からセッション情報を取得し,その内容でsignin
ページにリダイレクトするか,そのままdashboardページを開くか分岐させます.そのために/dashboard/layout.tsx
を以下のように編集します.
import { auth } from "@/auth" ;
import { redirect } from "next/navigation" ;
import React from "react" ;
export default async function DashboardLayout ({
children,
}: {
children: React.ReactNode;
} ) {
const session = await auth ();
if (!session) {
redirect ("/signin" );
}
return <> {children}</> ;
}
import SignIn from "@/components/signin" ;
export default function SignInPage ( ) {
return (
<div className ="flex items-center justify-center min-h-screen bg-gray-100" >
<div className ="bg-white p-8 rounded shadow-md w-full max-w-md" >
<h1 className ="text-2xl font-bold mb-6 text-center" > Sign In</h1 >
<SignIn />
</div >
</div >
);
}
import { SignOut } from "@/components/sign-out" ;
export default function DashboardPage ( ) {
return (
<div className ="flex flex-col items-center justify-center min-h-screen bg-gray-100" >
<div className ="bg-white p-8 rounded shadow-md w-full max-w-2xl" >
<h1 className ="text-3xl font-bold mb-6 text-center" > Dashboard</h1 >
<p className ="mb-4 text-center" > Welcome to your dashboard!</p >
<div className ="flex justify-center" >
<SignOut />
</div >
</div >
</div >
);
}
これらのページを開いて,それぞれの挙動を確認しましょう.
次回は,バックエンドとの統合について解説していきます.
Auth.jsとRuby on Railsによるユーザ管理