Next.jsでGoogle認証APIを使ってみたら超簡単だった

はじめに
アプリケーションを開発する上でほとんどの場合必要なのがログイン機能。
そして、そのログイン機能も最近はGoogleアカウントひとつあれば、いろんなアプリケーションにログインできるようになっています。
今日はそんなGoogle認証機能の実装方法について、できるだけ手軽に試す方法を紹介したいと思います。
そもそも認証とは
認証とはネットワークやサービスへアクセスする際に、通信の相手が誰であるのかを確認、特定するための方法です。つまり、だれがログインしたか、今このアプリケーションを使っているのは誰かを特定する方法のことを指します。
もっともミニマムな設計としては、データベースでのパスワード管理です。特定のユーザーIDとパスワードが一致した場合、ユーザー情報を返却します。
しかし、実際にはパスワードを暗号化したり、ユーザーとしてデータベースにアクセスし続けるためにセッション管理をしなければいけなかったりと様々な要因で機能が複雑肥大化します。(この辺もいつかまとめたい)
これらを1から作るのはそれなりにコストがかかるため、Google等の安全で正確な認証機能を使わせていただこうというのが今回の試みです。
基本的な手順
実装は超簡単で大まかに分けると下記の3ステップです。
- Next環境とAuth.jsのセットアップ
- Google ConsoleのAPI設定を作成
- アプリケーション内で認証実装
環境構築
まずはNext.jsのプロジェクトを下記コマンドで作成します。今回は最新環境で試したいのでApp Routerを選択します。
npx create-next-app@14 next-auth-sample --typescript
次にAuth.jsを書きコマンドでアプリケーションにインストールします。基本的にはライブラリの公式ドキュメント通りに進めれば問題ありません。
npm install next-auth@beta
次に暗号化に用いるための環境変数を用意します。下記コマンドを実行すると自動で.env.localが生成されます。
npx auth secret
次にルート直下にauth.tsというファイルを作成し、以下のように記述します。後述しますが、このprovidersに認証で使いたいAPIのサービスを配列で渡します。
import NextAuth from "next-auth"
export const { handlers, signIn, signOut, auth } = NextAuth({
providers: [],
})
次に以下のパスでroute.tsファイルを作成し、APIのエンドポイントを作成します。
/app/api/auth/[…nextauth]/route.ts
import { handlers } from "@/auth"
export const { GET, POST } = handlers
Google Cloud Platformの設定
ここでは一旦コードから離れて、Google Cloud Platformで作業します。
ここで一番大切なのは、認証API設定時に発行されるクライアントIDとシークレットです。この二つを環境変数として設定することで、Auth.jsがよしなに認証実行してくれます。
まずは画面上部ヘッダー部分からプロジェクトの選択をクリックし、新しいプロジェクトを作成します。project名は任意です。


次にAPIとサービスから今回使用する認証APIを設定していきます。

OAuth同意画面を選択し、開始をクリックします。


アプリの情報を入力していきます。基本的に画面に従って設定すればOKです。

ここでは対象は外部を選択します。

OAuthクライアントを作成します。OAUTHクライアントを作成をクリックします。

アプリケーション名を任意で入力します。

連携するアプリケーションのURLを入力します。どのURLからアクセスがあるか、承認済みの場合はどのようにリダイレクトするかの設定です。

ここで重要なのはどのURLからGoogle側にアクセスするかであり、今回は開発環境で動作を確認したいため、localhostを設定します。リダイレクトは公式にもある通り、先に設定したURLに指定のパスを付け足すイメージでOKです。
設定が完了するとクライアントID等が発行されます。

これでGoogle Cloud Platform 側の設定は終了です。
providersの設定と.env設定
ここからコード側に戻ります。
まずは先述したauth.jsのprovidersに”Google”を設定します。驚くほど簡単です。
import type { NextAuthConfig } from "next-auth";
import Google from "next-auth/providers/google";
const authConfig: NextAuthConfig = {
providers: [
Google,
],
};
次にenv.localに上記で設定したクライアントIDとシークレットを設定します。
AUTH_SECRET=xxxxx
// 追記
AUTH_GOOGLE_ID=xxxxx
AUTH_GOOGLE_SECRET=xxxxx
これでおまかな準備はできました。厳密にやるのであればもう少し詳細な設定も必要なのですが今回はとにかく最小限で動きを見たいので割愛します。
いざ、画面実装
page.tsを下記のように書き換えます。(とんでもなく冗長ですが)
import { signIn, auth, signOut } from "@/auth";
export default async function Home() {
const session = await auth();
console.log(session);
return (
<>
{session !== null ? (
<>
<h1>{session.user?.name}がログインしたよ</h1>
<img src={session.user?.image as string} alt="user image" />
<form
action={async () => {
"use server";
await signOut();
}}
>
<button type="submit">Signout</button>
</form>
</>
) : (
<>
<h1>ログインしてね</h1>
<form
action={async () => {
"use server";
await signIn("google");
}}
>
<button type="submit">Signin with Google</button>
</form>
</>
)}
</>
);
}
最後にnpm run devで開発環境を立ち上げlocalhost:3000にアクセスします。
下記キャプチャのような画面になっているはずです。

実際にボタンを押してみましょう。
エラーの場合はこのような画面になります。様々な原因が考えられますが、.envで設定したクライアントIDやシークレットが誤っていることが多いです。

成功時はgoogleアカウントの選択画面に遷移します。お好きなアカウントを選んで処理を続けると元のアプリケーション画面に戻ります。


ユーザー名とユーザーアイコンの画像、そしてサインアウトボタンが表示されていれば動作確認は成功です。

Auth.jsの公式ドキュメントでも解説があります。とてもわかりやすかったので深掘りしたい方ぜひ。
バックエンドとの連携
今回は紹介していませんが、セッション管理をミドルウェアで設定したり、Google認証を呼んだ際にバックエンド処理でユーザーの登録などを挟み込めば簡単にログインできるアプリケーションを構築することができそうです。
他にも深掘りできそうなことは多々あるのですが、まずは手を動かしてみるのが大事です。
authを呼び出すだけでセッション管理勝手にしてくれるのがすごい!便利!簡単!と思いました。1時間くらいでできます。これを元に同じような機能を手作りしたい気持ちもあります。
さいごに
今回は最速で簡単にGoogleの認証APIを使ってみる試みでした。
認証はアプリケーションには必須の機能であり、中でもGoogle認証はユーザーの体感でも最も多く使われているのではないでしょうか。
皆さんもぜひ気軽にお試しください〜!
それでは!