認証の基本とAuth.js か Firebase Auth か:要件別の最適解
プログラミングスクールを卒業してから早二週間!
現在、スクールで卒業制作でつくったアプリを継続開発しております。
開発に設けられた期間は約1ヶ月だったのですが、チームビルディングや企画、技術調査、担当分け、開発、テスト、デプロイ設定、デモ作成……と一通りアプリ制作に関わる工程を体験できたのですが、締切に間に合わせることに全力集中で、振り返ってみると『技術調査や議論にもう少し時間を割いても良かったなあ』と感じています。
その一つが「認証」についてなのですが、当時はスクールの講座に組み込まれていたことから、学習コストの低さでFirebase Authenticationを選んでしまっていたので、改めてどのような選択肢があったのかやより堅牢で運用性の高いものにするにはどのような改善ができるのか、体系的にメモに残しておきたいと思いました。
この記事では、認証についての深掘りをしていきます✊
OWASP
「認証」の基本的な部分を理解する上で便利そうだなと思ったのがOWASP。
オワスプと読み、Open Web Application Security Project の略です。
アメリカ合衆国の非営利組織でWebアプリケーションのセキュリティ向上を目的としています。
そんなOWASPはチートシート集[1]を無料で提供しており、様々なセキュリティ分野で役立つ情報がまとまっています。
認証とは?
OWASP によれば、認証はパスワード・指紋・セキュリティトークンなどの認証子の有効性を判定し、その主張(あなた本人か?)が正しいかを確認するプロセスです。
認証にまつわる用語
- 認可:認証(だれか)ではなく「何を許すか」を決める権限付与のこと(例:このユーザーはプロフィール閲覧は可・編集は不可)。
- 認証プロバイダー: ログイン元となる方式や外部サービス(例:Google/Apple/GitHub、メール+パスワード等)。IdPが提供する個々のログイン手段を指すことが多い。
- IdP: ユーザーの本人確認を行い、IDトークン等を発行するアイデンティティ提供者(例:Firebase Auth / Auth0 / Keycloak)。
- セッション:ステートレス[2]なHTTP[3]に“継続する文脈”を与え、サーバ側に「この人はログイン中ですよ」などの状態を伝達する。
- セッションID:各ユーザーのセッションを一意に識別する推測困難な乱数。セッションIDの運搬(サーバ→ブラウザとブラウザ→サーバの行き来)にはCookieが使われることが多い。
- セッション管理:セッションIDの発行・検証・更新・失効を安全に行い、状態を継続させる運用と実装。
- クッキー:ブラウザに保存され同一ドメインへ毎回自動送信される小さなデータ
(画像引用元:「ITまとめノート」 リンク:画像に添付) - SSR: サーバーサイドレンダリング。サーバ側でHTMLを生成して返す方式のこと。
認証とは別の概念だが、サーバ側でCookieやヘッダ(JWT/セッションクッキー等)を読んでユーザーを識別し、ログイン必須ページの保護や個別データ取得に活用されることが多い。 - OAuth:パスワードを渡さずに、第三者アプリへ“利用権限(認可)”を委譲する仕組み(=本人確認そのものではない)。
- callback URL: 外部サービスでの処理後にユーザーを戻す“返却先URL”
- アクセストークン: APIへのアクセス権を示す短命のトークン(付与されたscopeの範囲でだけ使える)。
- JWT:署名付きの自己完結トークン[4]で、サーバ側の保存なしに認証情報や権限を運べるフォーマット(JSON Web Token)。
- トークン取得ヘルパー: 現在のリクエストやセッションからアクセストークン/IDトークンを安全に取り出すためのユーティリティ(例:getServerSession / getToken / 認証ヘッダを読む依存関数)。
- リダイレクト:指定した別URLへブラウザを移動させる応答(ログイン前後の遷移で多用)。
- Middleware: HTTP処理の途中に共通処理(認証チェック・権限制御・リダイレクト等)を挟む層。Next.js の middleware.ts など。
- matcher: どのパスにMiddlewareを適用するかを指定するパターン定義(例:/app/:path* だけに適用)。
認証の実装方法
少し横道に外れてしまいますが、技術選定のアプローチとして「Build vs. Buy」の考え方を紹介します。
Build vs. Buy
「Build vs Buy(ビルド対バイ)」とは、「自社で構築する(Build)」か「外部から購入する(Buy)」かを、コスト・スピード・運用負荷・柔軟性などの観点で比較検討する概念です。
ソフトウェア開発やIT投資の文脈で使われることが多く、自社開発のメリット・デメリットと、外部購入のメリット・デメリットを比較し、ビジネスニーズに最適な選択を指します。
小規模や初期フェーズでは、多くのリソースを投下しづらいため、既存の選択肢を使うのが現実的です。
認証においても「Build vs Buy(ビルド対バイ)」の観点で、実装方法が分けられます。
代表的な選択肢は3つあります。
- IDaaS(クラウド型)
- 例:Firebase Authentication / Auth0 / Amazon Cognito / Clerk / Supabase Auth
- 認証・ID管理をクラウド事業者に丸ごと任せ、SDK/管理UIで素早く導入する方式。
- すぐ安全に使えるのがメリット、細かいカスタムに限界&料金やサービス依存があるのがデメリット。
- 自前ホスト / OSS
- 例:Keycloak / FusionAuth / Ory / SuperTokens
- 自分でIdPを立てて運用し、要件に合わせて自由にカスタムできる方式(運用責任も自社)。
- 自由度が高く要件に合わせやすいのがメリット、設計・運用・セキュリティ対応を自分で全部やる負担が大きいのがデメリット。
- フレームワーク用ライブラリ
- 例:Auth.js / Passport.js / django-allauth / Spring Security
- アプリ内に認証機能を実装する部品で、設計・発行・保守を自分で担う方式。
- 軽く始められてアプリにぴったり作れるのがメリット、トークン発行や失効など“面倒な部分”も自作・保守が必要なのがデメリット。
筆者はアプリ開発時、認証フレームワークの存在を把握しておりませんでした・・。
Auth.js(NextAuth.js発のコミュニティ製OSS)の存在を知っていれば、もっと簡単に実装できていたかも👀 と思ったので、次項からはAuth.jsとFirebase Authのそれぞれの特徴を解説します。
※他にもいろいろなIDaaSやフレームワークライブラリがありますが、今回は既にアプリで実装中のFirebase Authenticationと、Next.jsと相性が良いAuth.jsにフォーカスしたいと思います。
Auth.jsとは?
「Auth.js(旧 NextAuth.js)」は、複雑なWebアプリケーションの認証機能を簡単に実装するためのオープンソースライブラリです。
((主な特徴))
- Next.js での使いやすさ(もともとNextAuth.jsがNext.js向けにつくられたライブラリでした。現在はフレームワーク非依存なので他でも使えます)
- 複数の認証プロバイダーのサポート
- マジックリンク[5]認証のサポート
- JWT やデータベースセッション管理
- 柔軟なコールバックとイベントフック
- セキュリティ対策が標準装備(CSRF 保護など)
参考にしたページ: Zenn Auth.js v5 の紹介と導入【Next.js】
Firebase Authenticationとは?
Firebase Authentication(以下Firebase Auth)は、SNSのアカウントを使った認証、いわゆるソーシャルログインや、電話番号認証、メールとパスワードに基づく認証など、アプリで必要な認証を実装するための機能です。
Firebase Authでは認証機能を実装するためのSDKが提供されており、これを利用することでユーザー認証機能の開発のコストを低減できます。
Firebase Authと Auth.js の主な類似点と相違点
-
認証プロバイダー
- Firebase:メール/パスワード・電話・匿名・主要OAuth
- Auth.js:多数のOAuth、Email(マジックリンク)、Credentials(自前API)に対応。
-
バックエンド管理(どこにハンドラを置くか)
- Firebase:認証バックエンドはGoogle側。アプリはSDKで利用し、必要ならAdmin SDKでトークン検証
- Auth.js:アプリ側に“認証ハンドラ(ルート)”を1つ置くのが基本。Next.js(App Router)なら app/api/auth/[...nextauth]/route.ts を用意し、Route HandlerでOAuthコールバックやセッショントークン(JWT/DB)を処理。
-
SSR/サーバー側での扱いやすさ[6]
- Firebase Auth:SSRでユーザー判定が要る場合は「IDトークン→セッションクッキー化→Admin SDKで検証」と配線が必要
- Auth.js:サーバー側で
auth()
/getServerSession
からセッションを即取得でき、Middlewareでの保護も簡単
-
ホスティングとデプロイメント
- Firebase:Firebase HostingやGCPと相性◎(必須ではない)。
- Auth.js:複数フレームワーク/ランタイム対応なので、Next.jsを動かせる(あるいは対応アダプタのある)環境なら広く展開可。
-
セッション管理
- Firebase:ID/Refreshトークン(+SSR向けセッションクッキー)
- Auth.js:JWTセッションがデフォルト(DBを入れるとDBセッションも可)。
-
セキュリティ
どちらも安全なログインとセッション管理を提供します。- Firebase:Googleの運用基盤・ガイドラインに則る。
- Auth.js:認証ルートでのCSRF対策(ダブルサブミットCookie)やCookie属性管理、JWT暗号化などが標準。
参考にしたページ: Authentication in Next.js: Firebase vs NextAuth(LevelUp)
Firebase Auth と Auth.js どちらを選ぶ?
- Next.jsだけで完結&SSR/Middlewareを手早くやりたい → Auth.js
- 特定サービスの仕様・料金に縛られにくくしたい(ベンダーロック回避) → Auth.js(OAuth/OIDC準拠+自前DB中心で設計しやすい)
- 設計・運用・セキュリティの責任は外部に委託したい → Firebase
- Web(Next.js)とモバイル(iOS/Android/Flutter等)で、同じユーザーIDを共有したい場合、 → 共通基盤が使えるFirebase(Auth.jsはサーバ側の認証ライブラリなので、モバイルアプリ内で直接は使わない)
- 電話番号・匿名認証が必須 → Firebase
整理してみると、どちらが優れているというのは一概に言えないので用途や実装コストを踏まえて選定すべきだなと思いました🧐
-
何かを操作したり記述する際によく参照される情報を、簡潔な表現や表記で一枚から数枚の紙にまとめて一覧できるようにしたもの。 ↩︎
-
状態(ステート)を覚えないという意味。つまり HTTP は“前の会話を覚えない”。ブラウザがページを開くたび、ブラウザ:毎回「これください!」と必要情報を全部つけてサーバに送る→サーバはそのリクエストだけ見て返事し、終わったら忘れるという単発のやり取りになっている ↩︎
-
Webブラウザとサーバがやり取りするための通信のルール(プロトコル)のこと。 ↩︎
-
改ざん防止の“電子署名”が付いていて、中に“誰・いつまで有効・何ができる”など必要情報が完結して入っているトークン。使用の流れは、発行者(IdP/サーバ)がサイン済みトークンを作る→クライアントがAPIへ送る(多くはAuthorizationヘッダやHttpOnly Cookie)→受け手(バックエンド)は署名と有効期限・オーディエンス等を検証してアクセス可否を決める。 ↩︎
-
パスワードを使わず、メールで届く “1回だけ有効なログイン用リンク” をクリックしてサインインする方式。 ↩︎
-
サーバー側(描画やAPI処理の場)で認証状態やユーザー情報を直接扱えるようにする設計。Auth.jsはこの部分が関数1つで楽、Firebase Authはセッションクッキー+Admin SDK検証を自前で組む、という違いがあります。 ↩︎
Discussion