【ITニュース解説】Integrating Auth0 Authentication with NestJS Using Organizations (Multi-Tenant Setup)
2025年09月13日に「Dev.to」が公開したITニュース「Integrating Auth0 Authentication with NestJS Using Organizations (Multi-Tenant Setup)」について初心者にもわかりやすく解説しています。
ITニュース概要
Auth0とNestJSを連携させ、マルチテナントSaaSの認証システムを構築する。Auth0の「組織」機能でアプリケーションのテナントを管理し、JWT認証でAPIを保護する。NestJSでの設定からトークン取得まで手順を示し、テナントごとの認証とデータ分離を実現する。
ITニュース解説
この記事は、複数の顧客(テナント)が共有するソフトウェアサービス(マルチテナントSaaSアプリケーション)を構築する際に、NestJSというフレームワークを使ってAuth0という認証サービスを導入し、ユーザー認証を実現する方法について解説する。特に、Auth0の「Organization」機能を利用して、アプリケーションのテナントを管理する手法に焦点を当てている。
まず、マルチテナントSaaSアプリケーションとは、一つのソフトウェア基盤を多くの顧客がそれぞれ独立した環境として利用する形式のサービスを指す。例えば、クラウド上で提供される会計ソフトや顧客管理システムなどがこれにあたる。このようなアプリケーションでは、各顧客(テナント)のデータやアクセス権限を厳密に分離し、それぞれのユーザーが自分たちのテナントにのみアクセスできるようにする「認証」の仕組みが不可欠となる。Auth0はこの認証プロセスを簡単に実現するための外部サービスであり、NestJSはNode.jsでサーバーサイドアプリケーションを効率的に構築するためのフレームワークである。
Auth0では、「テナント」と「Organization」という二つの概念が存在し、初心者には混同しやすい点である。Auth0の「テナント」は、開発、ステージング、本番といった環境を分けるために利用され、セキュリティ境界としても機能する。一方、Auth0の「Organization」は、まさにマルチテナントSaaSアプリケーションにおける個々の顧客(テナント)を表現するために設計された機能である。アプリケーションは一つのAuth0テナント内で運用されるが、その中に複数のOrganizationを作成し、それぞれのOrganizationがアプリケーションの顧客に対応する形となる。
具体的な実装手順は、まず基本的なNestJSアプリケーションを用意するところから始まる。次に、Auth0のアカウントを作成し、そこで「アプリケーション」を登録する。このアプリケーションは、ユーザーがログインを行うためのフロントエンド(クライアント)とAuth0の間を取り持つ役割を果たす。アプリケーションの種類としては、ウェブブラウザからアクセスするサービスを想定し、「Regular Web Application」を選択する。この設定では、Auth0から発行されるDomain、Client ID、Client Secretといった情報が、後でNestJSアプリケーションからAuth0にアクセスする際に必要となるため、控えておく必要がある。また、ログイン後のリダイレクト先やログアウト後のURLなども、セキュリティのために正確に設定しておく。
続いて、NestJSアプリケーションがアクセスするAPIのために、Auth0上に「API」を定義する。これはアプリケーションがユーザーを認証した後に、バックエンドのAPIにアクセスする際に使用するアクセストークンを発行するための設定であり、ここで設定する「識別子(Audience)」が重要となる。そして、最も重要な「Organization」を作成する。これが、アプリケーションの個々の顧客(テナント)に相当する。Organizationを作成したら、そのOrganizationに所属するユーザーを招待する。Auth0は招待メールを送信し、ユーザーはそのメール内のリンクを通じてパスワードを設定し、指定されたOrganizationにサインアップする。この際、招待リンクにはユーザーが所属すべきOrganizationのIDが含まれているため、Auth0はどのOrganizationにユーザーを関連付けるかを正しく認識できる。
ユーザーが招待を承諾し、Auth0でログインプロセスを完了すると、Auth0は認証コード(Authorization Code)をアプリケーションにリダイレクトする。この認証コードは、ユーザーが認証されたことを示す一時的なものであり、直接ユーザー情報やアクセス権限を持つわけではない。NestJSアプリケーションは、この認証コードとAuth0から提供されたClient ID、Client Secretなどを用いて、Auth0のトークンエンドポイントにリクエストを送信し、アクセストークンを取得する。このアクセストークンが、ユーザーがNestJSの保護されたAPIにアクセスするための鍵となる。
NestJSアプリケーション側では、このアクセストークンを検証し、APIへのアクセスを許可する仕組みを構築する。具体的には、passportやpassport-jwtといった認証関連のライブラリをインストールする。そして、JWT(JSON Web Token)を検証するためのJwtStrategyというクラスを作成する。このStrategyでは、アクセストークンがAuth0によって正しく署名されたものであるか、期限が切れていないか、適切な「Audience」と「Issuer」を持っているかなどを検証する。これらの情報は、アクセストークン自体に含まれるか、またはAuth0の公開鍵が公開されているURL(jwksUri)から取得して検証が行われる。このJwtStrategyをNestJSの認証モジュール(AuthModule)に登録し、アプリケーションのルートモジュール(AppModule)にインポートすることで、認証システムがアプリケーション全体で利用可能になる。
最後に、保護したいAPIエンドポイント(例として、/パスのAPI)に@UseGuards(AuthGuard('jwt'))というデコレーターを付与する。これにより、そのエンドポイントへのリクエストには有効なアクセストークンが必要となる。有効なアクセストークンがリクエストヘッダーに含まれていない場合や、トークンが無効な場合は、NestJSはリクエストを拒否する。認証が成功した場合、アクセストークンに含まれるユーザー情報(サブジェクトIDや所属OrganizationのIDなど)は、NestJSのrequestオブジェクトを通じてコントローラーやサービスからアクセスできるようになる。特に、org_idという情報がトークンに含まれていることで、APIはリクエスト元がどのテナントに属するユーザーであるかを識別し、テナントごとのデータアクセスやビジネスロジックを適用できる。必要であれば、ログイン時に追加のスコープ(openid profile emailなど)を指定することで、より詳細なユーザー情報をアクセストークンに含めることも可能である。
これらの手順を通じて、NestJSアプリケーションはAuth0のOrganizations機能を活用し、堅牢なマルチテナント認証システムを構築し、テナントごとのロジックを適切に処理できるようになるのである。