ホームページ  >  記事  >  バックエンド開発  >  認証と認可 - 正しい方法!

認証と認可 - 正しい方法!

Mary-Kate Olsen
Mary-Kate Olsenオリジナル
2024-10-09 06:14:29776ブラウズ

Authentication and Authorization - the correct way!

ユーザーを認証する必要がある Web アプリまたはモバイル アプリを構築していると想像してください。おそらく、ソーシャル メディア プラットフォーム、電子商取引サイト、または単なるダッシュボード用です。ある時点で、「ユーザーを安全にログイン状態に保つにはどうすればよいでしょうか?」と自問することになるでしょう

そこで認証が登場します。しかし、セッション管理、認証トークン、人気が高まっている JWT (JSON Web Token) など、さまざまな方法から選択できるため、どれがアプリに適しているかを判断するのはあまり明確ではありません。では、どうやって決めるのですか?

JWT についてよく聞いていて、誇大宣伝する価値があるのか​​と疑問に思っているなら、あなたは正しい場所にいます。このブログ投稿では、JWT とは何か、JWT がどのように機能するか、Django の他の一般的な認証方法とどのように比較するかを詳しく説明します。最終的には、JWT をいつ使用するか、および JWT をセッションベースの認証や認証トークンなどの他のオプションと比較する方法を明確に理解できるようになります。飛び込んでみましょう!

JWT(JSONウェブトークン)とは何ですか?

JWT (JSON Web Token) は、当事者間で情報を安全に送信するために使用されるコンパクトで URL セーフなトークン形式です。これは、Web アプリケーションやモバイル アプリケーションなど、クライアントがリソースへのアクセスを要求する認証プロセスでよく使用されます。

JWT は 3 つの部分で構成されます:

ヘッダー: タイプ (JWT) や署名アルゴリズム (HS256 など) など、トークンに関するメタデータが含まれます。

ペイロード: ユーザーの ID、ユーザー名、ロールなどのユーザー固有のクレームが含まれます。

署名: 秘密鍵を使用してヘッダーとペイロードに署名することで、トークンが改ざんされていないことを保証します。

サンプル JWT は次のようになります:

eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1c2VybmFtZSI6ImpvaG4iLCJleHAiOjE2MjEyMzY5MjZ9.GG7h8oV2C7Mcp93JK...

JWT は一般的に ステートレス 認証で使用されます。つまり、サーバーはセッション データを保存しません。代わりに、必要なすべての情報 (クレーム) がトークン自体に埋め込まれます。

JWT の仕組み: 段階的なプロセス

簡単なシナリオで JWT 認証がどのように機能するかを詳しく見てみましょう。

1.ユーザーログイン
ユーザーはログイン フォームを介して自分の電子メールとパスワードを送信します。サーバーは認証情報を検証し、認証情報が正しければ、サーバーはユーザーの情報 (ID、ユーザー名、ロールなど) を含む JWT を生成します。

2.トークンがクライアントに送信されました
JWT が生成されると、通常は応答本文に含めてクライアントに送り返されます。クライアントは、このトークンを (ブラウザーの localStorage または sessionStorage、またはモバイル デバイスに安全に) 保存します。

3.ユーザーが保護されたリソースをリクエスト
クライアントは、保護されたルートにアクセスする必要があるときは常に、リクエストの Authorization ヘッダーで JWT を送信します。

Authorization: Bearer <JWT_TOKEN>

サーバーはリソースへのアクセスを許可する前にトークンを検証し、その有効性と整合性を確認します。

4.トークンの有効期限と更新
JWT トークンには有効期限 (5 分など) があるため、有効期限が切れると、ユーザーは再度ログインすることなく、リフレッシュ トークンを送信して新しい JWT を取得できます。

5.ユーザーがログアウトしました
ユーザーがログアウトすると、通常、リフレッシュ トークンはブラックリストに登録され (ブラックリスト登録をサポートするセットアップの場合)、ユーザーは実質的にログアウトされ、トークンを更新できなくなります。

Django における JWT と従来の認証方法の比較

JWT は、Django アプリケーションに認証を実装する多くの方法の 1 つです。 JWT を、セッション管理認証トークン などの他の一般的な方法とどのように比較するかを見てみましょう。

1. JWT 認証とセッション管理

セッション管理:
セッションベースの認証では、ユーザーがログインすると、サーバーがセッションを作成し、データベースまたはメモリに保存します。その後、セッション ID が Cookie を介してクライアントに送信されます。クライアントはセッション ID を保存し、リクエストごとにそれを送信します。その後、サーバーはストレージからセッション データを取得してユーザーを識別します。

現実世界のシナリオ:

E コマース Web サイト: オンライン ストアにログインし、商品をカートに追加し、チェックアウトに進むと想像してください。製品の表示やカートの更新など、このセッション中のすべてのアクションは、サーバーに保存されているセッション ID に関連付けられます。ログアウトすると、セッションは破棄されます。

JWT 対セッション:

- ストレージ:

  • JWT: ステートレス、サーバー側ストレージなし。すべてのデータはトークン自体の中に含まれています。
  • セッション: ステートフル。サーバーはセッション データを (通常はデータベースまたはメモリに) 保存し、セッション ID がクライアントに送信されます。

- スケーラビリティ:

  • JWT: 拡張性が高い。ユーザーセッション情報を保存する必要がないため、サーバー間で水平方向に拡張することが容易になります。
  • セッション: スケーラビリティが低い。サーバー間でセッション データを管理および共有する必要があります (例: 集中セッション ストアの使用)。

- データ転送:

  • JWT: トークンにはすべてのユーザー データ (クレーム) が含まれており、各リクエストとともに送信されます。データが多すぎるとサイズが大きくなる可能性があります。
  • セッション: セッション ID のみが送信され、ユーザー データはサーバーから取得されます。

- セキュリティ:

  • JWT: トークンがクライアント (ローカル ストレージなど) に安全に保存されていない場合に脆弱です。トークンの有効期限を処理し、安全に更新することが重要です。
  • セッション: 通常、セッション ID の保存に Cookie を使用します。HTTP 専用フラグとセキュア フラグを使用すると、より安全になります。ただし、CSRF 攻撃に対して脆弱になる可能性があります。

- 有効期限と管理:

  • JWT: トークンには有効期限があります。リフレッシュトークンを使用すると、再認証なしでアクセストークンを更新できます。
  • セッション: セッションにもタイムアウト期間がありますが、ユーザーがアプリを操作している限り簡単に延長できます。

- トークン サイズ:

  • JWT: すべてのデータがトークンに含まれるため、特に多くのユーザー情報やメタデータを運ぶ場合、JWT は大きくなる可能性があります。
  • セッション: 各リクエストではセッション ID のみが送信されるため、データ転送は最小限です。

- 使用法:

  • JWT: 最新のステートレス API、シングルページ アプリケーション (SPA)、およびモバイル アプリで推奨されます。
  • セッション: サーバーがユーザー状態を管理する従来の Web アプリケーションで一般的です。

2. JWT 認証と認証トークン

認証トークン:
トークンベースの認証 (Django の組み込みトークン認証など) では、ユーザーがログインすると、サーバーは一意のトークンを生成します。このトークンはサーバーに保存され、クライアントに送信され、すべてのリクエストに含まれます。サーバーはデータベース内のトークンをチェックしてユーザーを確認します。

現実世界のシナリオ:

API アクセス: API プロバイダー (GitHub など) は、ログイン後にユーザーの API トークンを生成します。GitHub API を操作するたびに、トークンはリクエストを認証するためにリクエスト ヘッダーに渡されます。 .

JWT 対 認証トークン:

- トークンストレージ

JWT (JSON Web トークン):

ステートレス: JWT は自己完結型であり、必要な情報 (クレーム) がすべてトークン自体の中に保存されることを意味します。サーバーはトークンを保存しないため、ステートレス システムになります。
トークンは通常、クライアント側 (localStorage、sessionStorage、Cookie など) に保存され、Authorization ヘッダー内のすべてのリクエストとともに送信されます。

認証トークン:

ステートフル: 従来のトークンベースの認証では、トークンが生成され、サーバー側 (多くの場合データベース) に保存されます。サーバーはトークンを追跡し、クライアントはそれを各リクエスト (通常はヘッダー) に含めます。

- トークン構造

JWT:

自己完結型: JWT トークンは、ヘッダー、ペイロード、署名の 3 つの部分で構成されます。ペイロードにはユーザー情報 (ID、電子メール、役割など) が含まれており、整合性を確保するために署名されています。

認証トークン:

不透明なトークン: 認証トークンは通常、不透明な文字列であり、ユーザー情報をまったく含まないことを意味します。これらは、サーバー側のセッションまたはユーザー データへの参照として機能します。
サーバーはこのトークンを使用して、サーバーに保存されているセッションまたはユーザー情報を検索します。

- サーバーのストレージとスケーラビリティ

JWT:

サーバーストレージなし: JWT トークンは自己完結型であるため、サーバーはセッションやトークンのデータを保存する必要がありません。これにより、特に複数のサーバーが関与する可能性のある分散システムやマイクロサービス アーキテクチャにおいて、拡張性が高くなります。

認証トークン:

サーバー側ストレージ: 認証トークンはサーバー上のデータベースまたはメモリに保存されます。つまり、サーバーはリクエストごとにトークンを追跡し、検証する必要があります。サーバーはリクエストごとに中央のセッション ストアにアクセスする必要があるため、これはスケーラビリティが低下する可能性があります。

- セキュリティに関する考慮事項

JWT:

署名ベース: JWT トークンは、トークンが改ざんされていないことを保証するために、HS256 や RS256 などのアルゴリズムを使用して署名されます。これによりトークンの整合性は保護されますが、データは暗号化されません。機密データは、暗号化されない限りペイロードに含めるべきではありません。

クライアント側のリスク: JWT は localStorage または sessionStorage に保存されることが多いため、XSS (クロスサイト スクリプティング) 攻撃に対して脆弱になる可能性があります。これを軽減するために、HTTP 専用 Cookie に保存できます。

認証トークン:

サーバー側の検証: 認証トークンにはユーザー情報が含まれておらず、サーバー上のセッションに対して検証されるため、改ざんに対してより安全であると考えられます。ただし、適切に処理しないと、セッション ハイジャックや CSRF (クロスサイト リクエスト フォージェリ) 攻撃に対して脆弱になります。

- 有効期限とトークンの有効期間

JWT:

有効期限の短いアクセス トークン: JWT は通常、有効期限が短い (例: 5 ~ 15 分)。有効期限が切れると、クライアントはリフレッシュ トークンを使用して新しいアクセス トークンを取得する必要があります。これは、JWT のセキュリティ モデルの重要な部分です。
リフレッシュ トークン: 有効期間の長いリフレッシュ トークンを使用すると、ユーザーは資格情報を頻繁に再入力しなくてもログインを維持できますが、独自のセキュリティ上の課題もあります (安全に保存および管理する必要があるなど)。

認証トークン:

デフォルトでトークンの有効期限なし: サーバーによって明示的に処理されない限り、認証トークンはデフォルトで期限切れになりません。サーバーはトークンを取り消したり期限切れにしたりできますが、これにはトークンの有効期限を追跡するための追加のロジックとストレージが必要です。

- トークン サイズ

JWT:

より大きなトークン サイズ: JWT にはユーザー情報 (クレーム) と署名が含まれるため、不透明な認証トークンと比較してサイズが大きくなる傾向があります。これにより、特にリクエストが頻繁に発生するシナリオでは、帯域幅の使用量がわずかに増加する可能性があります。

認証トークン:

トークン サイズの縮小: 認証トークンは通常、不透明な文字列であるため、サイズがはるかに小さくなります。これらは識別子として機能し、追加のデータを伝送しないため、使用する帯域幅が少なくなります。

- 使用シナリオの例

JWT:

シングル ページ アプリケーション (SPA): JWT は、ステートレス認証が必要でサーバー側のセッション管理が必要ない SPA (React や Angular など) とうまく連携します。

マイクロサービスと API: JWT は、複数のサービスがサーバー間でセッション状態を共有せずにユーザーを認証する必要がある API とマイクロサービス アーキテクチャに最適です。
認証トークン:

従来の Web アプリ: サーバーでレンダリングされる Web アプリケーションでは、サーバー側で保存および検証される認証トークン (またはセッション) が一般的に使用され、セッションの維持が簡単なアプリケーションに適しています。
小規模アプリケーション: 認証トークンは、セッション管理がスケーラビリティの問題にならない、ユーザーの少ないアプリケーションに適しています。

- 無国籍とステートフルネス

JWT:

ステートレス: JWT はサーバー側のストレージを必要としないため、アプリケーションをステートレスにします。これは、サーバー間でセッションを同期する必要がないため、複数のサーバー間で水平にスケーリングする場合に有益です。
認証トークン:

ステートフル: 認証トークンにはサーバー側のセッション ストレージが必要です。つまり、サーバーがセッション データを追跡します。これは小規模なアプリケーションには問題ありませんが、中央のセッション ストア (Redis など) を使用しない限り、複数のサーバーに拡張する場合には問題が発生する可能性があります。

- ブラックリストへの登録と取り消し

JWT:

取り消しが難しい: JWT はステートレスでサーバーに保存されないため、トークンのブラックリストを使用しない限り、一度発行された JWT を取り消すのは困難です。これは、トークンが侵害された場合でも、有効期限が切れるまで有効なままであることを意味します。

ブラックリスト登録が必要: トークンの取り消し (ログアウト時など) を処理するには、無効化されたトークンを追跡するブラックリスト メカニズムをサーバーに実装する必要があります。

認証トークン:

取り消しが簡単: 認証トークンはサーバーに保存されるため、取り消しや無効化は簡単です。

3. JWT 認証と Basic 認証の比較

基本認証:
基本認証では、クライアントはすべてのリクエストでユーザーの資格情報 (ユーザー名とパスワード) を送信します。これは通常、base64 でエンコードされます。この方法は、内部システムや単純なセットアップでよく使用されます。

現実世界のシナリオ:

内部管理者ダッシュボード: 小規模企業の内部管理者ダッシュボードでは、ユーザーは基本認証でログインする必要があります。ユーザーがページにアクセスすると、その認証情報がリクエストで送信されます。

現実世界のユースケース: JWT をいつ使用するか?

実際の例を考えてみましょう。ユーザーがログインし、投稿を操作し、複数のデバイスでプロフィールを管理するソーシャル メディア プラットフォームです。

そのようなシステムでは:

  1. JWT はステートレスであるため、適切に機能します。つまり、サーバーはユーザー セッションを保存する必要がありません。
  2. クライアントはトークンをローカルに保存できるため、ユーザーはさまざまなタブやデバイスにまたがってログインしたままにすることができます。
  3. アプリは複数のサーバー (たとえば、1 つのサーバーで投稿を処理し、もう 1 つのサーバーでプロファイル) にわたって水平に拡張できるため、JWT を使用すると、中央のセッション ストアを必要とせずに簡単に拡張できます。
  4. ユーザーはトークンを定期的に更新して、再度ログインすることなくアクセスを維持することもできます。

結論: どの認証方法を選択するべきですか?

適切な認証方法の選択は、アプリケーションの要件によって異なります。

JWT は、ステートレスでスケーラブルなアプリケーション (SPA、モバイル アプリ、マイクロサービスなど) に最適です。
セッションベースの認証は、スケーラビリティが大きな問題ではない従来の Web アプリケーションに適しています。
認証トークンは、サーバー側のトークン ストレージを管理できる小規模 API 認証のためのシンプルで安全な方法です。

各方法には長所と短所がありますが、JWT は、スケーラビリティと柔軟性が鍵となる最新の分散システムを処理できるという点で際立っています。

以上が認証と認可 - 正しい方法!の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

声明:
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。