【Next.js】NextAuth.jsでGoogleログイン機能の実装方法
はじめに
個人開発でNextAuth.jsを使用して、Next.jsでGoogleログイン機能を作成したので、手順を紹介します。
Googleログインに必要な情報は別記事にて紹介しています。
環境
Next.js 14.2.4
NextAuth 5.0.0-beta.19
参照
実装手順
1. アプリの新規作成
以下のコマンドでNext.jsのアプリの新規作成します。
npx create-next-app@latest
必要な項目に回答していきます。
✔ What is your project named? … google_auth_login
✔ Would you like to use TypeScript? … No / Yes
✔ Would you like to use ESLint? … No / Yes
✔ Would you like to use Tailwind CSS? … No / Yes
✔ Would you like to use `src/` directory? … No / Yes
✔ Would you like to use App Router? (recommended) … No / Yes
✔ Would you like to customize the default import alias (@/*)? … No / Yes
✔ What import alias would you like configured? … @/* ←ここはEnterキーを押す
新規作成されていることを確認したら、
ls
google_auth_login
ディレクトリに移動して、エディタで立ち上げます。
cd google_auth_login/
以下のコマンドでNext.jsの画面が立ち上がったらセットアップは完了です。
npm run dev
2. Googleから必要な情報を取得
記事を参考にClientId
とClientSecret
を取得します。
3. Googleから取得した情報をenvファイルの設定
Googleの情報をenvファイルに記載して参照出来るようにします。
AUTH_URL
にはCallback URL
を設定します。
AUTH_SECRET
には32バイトのランダムデータを生成し、それをBase64形式でエンコードします。
openssl rand -base64 32
// GoogleのCallback URL
AUTH_URL="http://localhost:3000/api/auth"
AUTH_SECRET="openssl rand -base64 32で生成されたデータを記載"
GOOGLE_CLIENT_ID="Googleから取得したClientId"
GOOGLE_CLIENT_SECRET="Googleから取得したClientSecret"
4. NextAuth.jsをインストール
公式を参考にNextAuth.jsをインストールします。
npm install next-auth
5. 認証機能を設定
画像の設定
thema
に画像を設定すると、指定した画像の表示が出来ます。
Google認証プロバイダの設定
Google OAuth
を使ってユーザー認証を行うために、Googleプロバイダをproviders
配列に追加しています。これにはClientId
とClientSecret
が必要で、これらは環境変数から取得されます。
NextAuthの設定
NextAuth関数を使用して認証関連の設定を行います。設定内容にはプロバイダの指定、APIのベースパス/api/auth
、そしてコールバック関数が含まれます。
認証コールバックの定義
authorizedコールバックで、ログイン後に利用できるページ(ここでは/protected-page
)へのアクセスがログイン認証されたユーザーに限定されるようにしています。
jwtコールバックでは、JWTトークンが更新された際にユーザー名をトークンに追加しています。
import { handlers } from '@/contexts/auth'
export const { GET, POST } = handlers
import Google from 'next-auth/providers/google'
import NextAuth, { NextAuthConfig } from 'next-auth'
import { Provider } from 'next-auth/providers'
const providers: Provider[] = [
Google({
clientId: process.env.GOOGLE_CLIENT_ID,
clientSecret: process.env.GOOGLE_CLIENT_SECRET,
}),
]
export const config: NextAuthConfig = {
theme: {
logo: '/login.png',
},
providers: providers,
basePath: '/api/auth',
callbacks: {
authorized({ request, auth }) {
try {
const { pathname } = request.nextUrl
// ログイン後のみ表示出来るページのパスを指定します。
if (pathname === '/protected-page') return !!auth
} catch (err) {
console.error(err)
}
},
jwt({ token, trigger, session }) {
if (trigger === 'update') token.name = session.user.name
return token
},
},
}
export const { handlers, auth, signIn, signOut } = NextAuth(config)
ミドルウェアのエクスポートと設定
認証機能をmiddlewareとしてエクスポートし、特定のパス(APIやNext.jsの内部処理に使われるパスを除く)でこのミドルウェアを適用するように設定します。
export { auth as middleware } from './auth'
export const config = {
matcher: ['/((?!api|_next/static|_next/image|favicon.ico).*)'],
}
6. 動作確認を行うためのViewの設定
import { auth } from '@/contexts/auth'
import { SigninBtn } from '@/components/auth/signin/btn'
import { SignoutBtn } from '@/components/auth/signout/btn'
export default async function Home() {
const session = await auth()
if (!session?.user) return <SigninBtn provider="Google" />
return (
<>
{session && (
<>
<p>ユーザーはログインしています。</p>
<SignoutBtn />
</>
)}
</>
)
}
注)src/app/globals.cssの記載は全て削除した状態で試しています。
ログインボタンのコンポーネント
import { signIn } from '@/contexts/auth'
import React from 'react'
export function SigninBtn({
provider,
...props
}: { provider?: string } & React.ComponentPropsWithRef<'button'>) {
return (
<form
action={async () => {
'use server'
await signIn(provider)
}}
>
<button
{...props}
className="hover:bg-green-100 border-green-500"
>
<div className="ml-2" />
<span>Googleでログイン</span>
</button>
</form>
)
}
ログアウトボタンのコンポーネント
import { signOut } from '@/contexts/auth'
import React from 'react'
export function SignoutBtn({
provider,
...props
}: { provider?: string } & React.ComponentPropsWithRef<'button'>) {
return (
<form
action={async () => {
'use server'
await signOut({ redirectTo: provider })
}}
className="w-full"
>
<button className="w-full p-0" {...props}>
ログアウト
</button>
</form>
)
}
7. 実装の確認
Googleでログイン
をクリックすると、Googleログイン画面へ遷移し、アカウントを選択すると、画像のようにログイン処理を行うことができました。
参照動画
こちらの動画を参考にしました。とてもわかりやすかったです。
Discussion