あなたの Express.js API を JWT と Logto で保護する
Express.js API エンドポイントを JSON Web Tokens (JWT) と Logto で保護する方法を学びます。
はじめに
ウェブアプリケーションを開発する際、APIエンドポイントを不正アクセスから保護することは非常に重要です。オンラインショッピングサイトを構築していると仮定してみてください。サイバー窃盗者がAPIを悪用するのは絶対に防ぎたいですよね。
ユーザー認証を使って特定のアクションを行う前にサインインする必要があるExpress.jsアプリケーションをすでに作成していると仮定します。そうでない場合は、Logto から始めることができます。ユーザー認証フローを確立するためにわずか数行のコードが必要です。
しかし、ユーザー認証後でもAPIエンドポイントを保護するためのさまざまな選択肢に直面します。残念ながら、これらのオプションのほとんどには欠点があります:
- セッションベースの認証: APIをセッションストアに結びつけることはスケーラブルではなく、マイクロサービスには適していません。
- 認証サービスの呼び出し: これは余分なネットワーク呼び出しを導入し、遅延とコストを増加させます。一部の認証サービスはAPIコールボリュームに基づく料金を課すことさえあり、膨大な費用につながる可能性があります。
このチュートリアルでは、JSON Web Tokens (JWT) と Logto を使用してAPIエンドポイントを強化する方法を示します。このアプローチはスケーラビリティを提供し、追加コストを最小限に抑えます。
前 提条件
始める前に、以下を確認してください:
- Logtoアカウント。持っていない場合は、無料でサインアップ できます。
- API保護が必要なExpress.jsプロジェクトとAPIを消費するクライアントアプリケーション。
- JSON Web Token (JWT) に対する基本的な知識。
LogtoでAPIリソースを定義する
Logtoは RFC 8707: OAuth 2.0のリソースインジケータ をフル活用してAPIエンドポイントを保護します。これにより、実際のURLを使用してAPIリソースを定義できます。
Logtoコンソールの「APIリソース」タブに移動し、「APIリソース作成」をクリックして新しいものを作成します。たとえば、/api/products
エンドポイントを保護したい場合は、識別子として https://yourdomain.com/api/products
を使用できます。
クライアントアプリケーションでアクセストークンを取得する
続行するには、Logto SDKをクライアントアプリケーションに統合する必要があります。このアプリケーションはExpress.jsバックエンドとは異なる可能性があります。例えば、バックエンドAPIサーバーとしてExpress.jsを使用したReactアプリを持っているかもしれません。
この助成金でAPIのアクセストークンを要求したいとLogtoに通知するためにLogto SDK構成を調整する必要もあります。以下はReactを使用した例です:
一旦ユーザーがLogtoでサインインすると、Logto SDK内のisAuthenticated
はtrue
になります:
これで、getAccessToken
メソッドを使ってAPIのアクセストークンを取得できます:
最後に、APIへのリクエストを行うときはAuthorization
ヘッダーにこのアクセストークンを含めてください:
APIでアクセストークンを検証する
Express.jsアプリケーションでJWTの検証用にjose
ライブラリをイン ストールします:
Bearer認証を使用しているので、Authorization
ヘッダーからアクセストークンを抽出します:
続いて、アクセストークンを検証するミドルウェアを作成します:
このミドルウェアを利用してAPIエンドポイントを保護できます:
このアプローチでは、リクエストが届くたびにLogtoサーバーに問い合わせる必要はありません。代わりに、LogtoサーバーからJSON Web Key Set (JWKS)を一度取得し、それ以降はローカルでアクセストークンを検証します。
役割ベースのアクセス制御
これまでのところ、ユーザーがLogtoでサインインしているかどうかを確認しただけです。ユーザーがAPIエンドポイントにアクセスする適切な権限があるかどうかはまだわかりません。これは、Logtoが既存のAPIリソースに対して誰にでもアクセストークンを発行できるためです。
これを解決するために、役割ベースのアクセス制御(RBAC)を使用できます。Logtoでは、役割を定義し、それに権限を割り当てることができます。このチュートリアル で、Logtoでの役割と権限の定義方法を学ぶことができます。
役割と権限を定義した後、LogtoProvider
コンポーネントにscopes
オプションを追加できます:
その後、Logtoはユーザーに適切なスコープを持つアクセストークンのみを発行します。たとえば、ユーザーがread:products
のスコープしか持っていない場合、アクセストークンにはそのスコープのみが含まれることになります:
ユーザーがread:products
とwrite:products
の両方のスコープを持っている場合、アクセストークンにはスペースを区切り文字として両方のスコープが含まれます:
Express.jsアプリケーションでは、APIエンドポイントへのアクセスを許可する前にアクセストークンが正しいスコープを含んでいるかどうかを確認できます:
結論
APIエンドポイントを保護しながらスケーラビリティを確保することは簡単ではありません。Logtoでは、開発者がリクエストの認証を簡素化できるように努めており、ビジネスロジックにより集中できるようにしています。
質問がある場合は、Discordサーバー に参加してください。コミュニティはいつでもあなたを助けることができます。