1. ホーム
  2. rest

[解決済み] RESTful APIはステートレスである」をどう理解するか?

2023-03-16 21:11:59

質問

があると聞いたのですが。 RESTful APIはステートレスであるべきだと聞きました。すべての状態情報はクライアント側で保持されるべき "です。

しかし、私がウェブページからAJAXコールを発行したとき、セッションIDクッキーが常にサーバーに一緒に送信されることに気づきました。そのセッションIDがあれば、サーバー上のセッションオブジェクトを取得することができ、その結果、" セッションの状態情報を取得/設定する となります。

これは、RESTful API のための "ステートレスであることのコード" を破るのでしょうか?

追加1

(質問の背景は以下の通りです。)

RESTful APIを呼び出して、ユーザー名とパスワードを検証するログインページを実装しようとしました。

ユーザーが私のサイトのあるページにアクセスしようとするたびに、ログイン用の servlet filter をチェックします。 session (これは getSession() が呼び出されます)、そのユーザーに対して有効なログイン情報が存在するかどうかを調べます。もしそうでなければ、ログインフィルターはユーザーをログインページにリダイレクトします。

ログインページでは、ユーザー名とパスワードを使ってサーバー上のRESTful APIにAJAXが呼び出されます。そのRESTful API呼び出しの結果に応じて、ページ上のJavaScriptはユーザーを私のサイトに入れるかどうかを決定します。

というわけで、このシナリオでは、なんとなく session .

詳細なコードはこちらにあります。 このRESTfulコールによるログインロジックは健全でしょうか?

どのように解決するのですか?

簡単に言うと、REST アプリケーションでは、各リクエストは、サーバーが以前のリクエストを覚えているかどうかに依存するのではなく、サーバーが理解するために必要なすべての情報を含んでいる必要があります。

サーバーにセッションの状態を保存することは、REST アーキテクチャのステートレス制約に違反します。そのため、セッションの状態は完全にクライアントによって処理されなければなりません。

詳細については読み進めてください。

セッションの状態

従来のWebアプリケーションでは リモートセッション . このアプローチでは アプリケーションの状態 は完全にサーバー上に保持されます。Roy T. Fielding の次の引用文をご覧ください。 学位論文 :

3.4.6 リモートセッション(RS)

リモートセッション形式は、サーバコンポーネントよりもクライアントコンポーネントの複雑さを最小化し、または再利用を最大化しようとするクライアントサーバの変種です。各クライアントはサーバー上でセッションを開始し、サーバー上の一連のサービスを呼び出して、最後にセッションを終了します。アプリケーションの状態は、すべてサーバー上に保持されます。[...]

この方法はいくつかの利点をもたらしますが、サーバーのスケーラビリティを低下させます。

リモートセッション形式の利点は、サーバーでインターフェイスを一元管理しやすく、機能が拡張されたときに配備されたクライアントでの不整合の心配が減ること、そして、サーバーで拡張セッションコンテキストを利用するインタラクションの場合は効率が改善されることです。欠点は、アプリケーションの状態が保存されるため、サーバーのスケーラビリティが低下することと、モニターがサーバーの完全な状態を知っている必要があるため、インタラクションの可視性が低下することです。

ステートレス制約

RESTのアーキテクチャスタイルは、以下のような制約の上に定義されています。 サーバーのステートレス化 . Fielding によれば、REST は ステートレス制約 は以下のように定義されています。

5.1.3 ステートレス

[...] クライアントからサーバへの各リクエストは、リクエストを理解するために必要なすべての情報を含んでいなければならず、サーバに保存されているコンテキストを利用することはできません。そのため、セッションの状態は完全にクライアント側で保持されます。[...]

この制約により 可視性 , 信頼性 そして スケーラビリティ :

要求の全容を把握するために、監視システムが1つの要求データ以外を見る必要がないため、可視性が向上します。部分的な障害から回復する作業が容易になるため、信頼性が向上します。スケーラビリティは、リクエスト間の状態を保存する必要がないため、サーバーコンポーネントがリソースを迅速に解放することができ、さらにサーバーがリクエスト間のリソースの使用を管理する必要がないため、実装が簡素化されることによって改善されます。

認証と認可

クライアントが認証を必要とする保護されたリソースを要求する場合、すべてのリクエストに 適切に認証/認可されるために必要なすべてのデータ . の引用をご覧ください。 RFC 7235 :

<ブロッククオート

HTTP 認証はステートレスであると仮定されています。リクエストを認証するために必要なすべての情報は、サーバーが以前のリクエストを記憶しているかどうかに依存するのではなく、リクエストの中で提供されなければなりません (MUST)。

そして認証データは、標準的な HTTP Authorization ヘッダーに属している必要があります。から RFC 7235 :

<ブロッククオート

4.2. 認証

この Authorization ヘッダフィールドは、ユーザエージェントがオリジンサーバで自分自身を認証することを可能にします。 401 (Unauthorized)応答を受け取った後です。 その値は、リクエストされたリソースの領域に対するユーザーエージェントの 認証情報を含むクレデンシャルから構成される。[...]

この HTTP ヘッダの名前は不幸なものです。 認証 の代わりに 認証 のデータを使用します。

認証には HTTP 基本認証 スキームを使用します。これは、ユーザー名とパスワードのペアを Base64 でエンコードして認証情報を送信します。

Authorization: Basic <credentials>

各リクエストでユーザー名とパスワードを送信したくない場合は、ユーザー名とパスワードをトークンと交換することができます (たとえば、次のようになります)。 JWT のような) トークンと交換し、各リクエストで送信することができます。JWT は、ユーザー名、有効期限、その他アプリケーションに関連するメタデータを含むことができます。

Authorization: Bearer <token>

サーバーに問題がある可能性があります

セッションIDを取得した時点で、HTTPセッションが作成されていると思われます。 どこかで が作成されているのでしょう。それはあなたの 自身のコード または フレームワークのコード のコードに記述してください。

Javaアプリケーションでは、以下のメソッドが ではなく が呼び出されないようにする必要があります。