web-dev-qa-db-ja.com

従来のWebアプリとAPIでの認証、承認、およびセッション管理

間違っている場合は修正してください:従来のWebアプリケーションでは、ブラウザーはセッション情報をサーバーへのリクエストに自動的に追加するため、サーバーはリクエストの送信元を知ることができます。実際に正確に何が追加されますか?

ただし、APIベースのアプリでは、この情報は自動的に送信されません。そのため、APIを開発するときに、たとえば認証されたユーザーからのリクエストであるかどうかを確認する必要がありますか?これは通常どのように行われますか?

73
Jiew Meng

HTTPプロトコルは設計上ステートレスであり、各リクエストは個別に実行され、個別のコンテキストで実行されます。

セッション管理の背後にある考え方は、同じクライアントからのリクエストを同じコンテキストに配置することです。これは、サーバーが識別子を発行してクライアントに送信することで行われ、クライアントはこの識別子を保存し、サーバーが識別できるように後続のリクエストで再送信します。

クッキー

一般的なブラウザサーバーの場合。ブラウザは、ドメインごとにCookieと呼ばれるキー/値ペアのリストを管理します。

  • Cookieは、Set-Cookie HTTP応答ヘッダーを使用して、サーバーで管理(作成/変更/削除)できます。
  • Cookie HTTP要求ヘッダーを解析することにより、サーバーはCookieにアクセス(読み取り)できます。

Webをターゲットにしたプログラミング言語/フレームワークは、たとえば、PHP提供 setcookie / $_COOKIE Cookieの書き込み/読み取り。

セッション

セッションに戻ります。通常のブラウザサーバーの場合(再び)、サーバー側のセッション管理はクライアント側のCookie管理を利用します。 PHPのセッション管理 セッションID Cookieを設定し、それを使用して後続のリクエストを識別します。

WebアプリケーションAPI?

質問に戻りましょう。 APIの設計とドキュメント化を担当するのはあなたであるため、実装はあなたの決定です。基本的に

  1. クライアントに識別子を与えます。これは、応答本文(XML/JSON認証応答)内のSet-Cookie HTTP応答ヘッダーを介して行われます。
  2. 識別子/クライアントの関連付けを維持するメカニズムがあります。たとえば、識別子00112233445566778899aabbccddeeffをクライアント/ユーザー#1337と関連付けるデータベーステーブル。
  3. hTTP Cookieリクエストヘッダー、?sid=00112233445566778899aabbccddeeff param(*)など、後続のすべてのリクエストで(1.)に送信された識別子をクライアントに再送信させます。
  4. (2.)のメカニズムを使用して受信した識別子を検索し、有効な認証かどうかを確認し、要求された操作を実行する権限があるかどうかを確認し、認証されたユーザーに代わって操作を続行します。

もちろん、既存のインフラストラクチャ上に構築でき、アプリでPHPのセッション管理(1./2と4の認証部分を処理します)を使用し、クライアント側の実装にCookie管理を要求することができます(それは3.)を処理します。その後、アプリロジックの残りの部分を実行します。


(*)各アプローチには長所と短所があります。たとえば、GETリクエストパラメータを使用すると実装が簡単ですが、GETリクエストがログに記録されるため、セキュリティに影響する場合があります。重要な(すべて?)アプリケーションにはhttpsを使用する必要があります。

120
aularon

セッション管理はサーバーの責任です。セッションが作成されると、セッショントークンが生成され、クライアントに送信されます(Cookieに保存されます)。その後、クライアントとサーバー間の次の要求で、クライアントはトークンを(通常)HTTP Cookieとして送信します。すべてのセッションデータはサーバーに保存され、クライアントはトークンのみを保存します。たとえば、PHPでセッションを開始するには、次の操作を行う必要があります。

session_start();  // Will create a cookie named PHPSESSID with the session token

セッションが作成されたら、セッションにデータを保存できます。たとえば、ユーザーをログに記録したい場合:

// If username and password match, you can just save the user id on the session
$_SESSION['userID'] = 123;

これで、ユーザーが認証されているかどうかを確認できます。

if ($_SESSION['userID'])
    echo 'user is authenticated';
else
    echo 'user isn't authenticated';       

必要に応じて、認証されたユーザーのみのセッションを作成できます。

if (verifyAccountInformation($user,$pass)){ // Check user credentials
    // Will create a cookie named PHPSESSID with the session token
    session_start();
    $_SESSION['userID'] = 123;
}

WebアプリケーションとAPIの両方について、本物のユーザーには多くの方法があります。いくつかの標準がありますが、独自のカスタム認証や認証を作成することもできます。承認と認証の違いを指摘したいと思います。まず、アプリケーションは、リクエストの送信元であるユーザー(またはAPIクライアント)を認証する必要があります。ユーザーが認証されると、ユーザーのIDアプリケーションに基づいて、認証されたユーザーが特定のアプリケーション(承認)を実行する権限を持っているかどうかを判断する必要があります。従来のほとんどのWebアプリケーションでは、セキュリティモデルに細かな細分性はありません。そのため、ユーザーが認証されると、ほとんどの場合、特定のアクションの実行も許可されます。ただし、この2つの概念(認証と承認)は、2つの異なる論理操作として行う必要があります。

さらに、従来のWebアプリケーションでは、ユーザーが認証および承認された後(主にデータベースでユーザー名/パスワードのペアを検索することによって)、承認およびID情報がセッションストレージに書き込まれます。上記の回答のほとんどが示すように、セッションストレージはサーバー側である必要はありません。クライアント側のCookieに保存され、ほとんどの場合暗号化されます。たとえば、PHP CodeIgniterフレームワークはデフォルトでこれを実行します。クライアント側でセッションを保護するためのメカニズムは数多くありますが、セッションIDを保存するよりも安全性が低いセッションデータを保存するこの方法は、サーバー側のセッションストレージで検索されます。また、セッションのクライアント側の保存は、サーバー側での中央セッション管理のためのソリューションの設計(または既存のソリューションの使用)が不要になるため、分散環境では非常に便利です。

さらに、データベース内の一致するユーザーレコードを検索するカスタムコードを使用して、単純なユーザーとパスワードのペアによる認証を行う必要はありません。たとえば、 基本認証プロトコル または ダイジェスト認証 があります。 Windowsプラットフォームのようなプロプライエタリなソフトウェアでは、たとえば、 ActiveDirectory のように、ユーザートラフを認証する方法もあります。

ユーザー名/パスワードのペアを提供することは、HTTPSプロトコルを使用する場合の認証方法であるだけでなく、認証を考慮することもできます デジタル証明書を使用

特定のユースケースで、プロトコルとしてSOAPを使用するWebサービスを設計する場合、SOAPプロトコルの WS-Security 拡張もあります。

これらすべてを述べた上で、次の質問に対する答えは、WebApiの承認/認証メカニズムを選択するための決定手順を入力すると言うでしょう。

1)ターゲットオーディエンスは何ですか、それは一般に利用可能ですか、または登録済み(有料)メンバーのみですか?
2)実行されているか、* NIX、またはMSプラットフォームか
3)予想されるユーザー数
4)機密データAPIが処理する量(より強力な認証メカニズムとより弱い認証メカニズム)
5)使用できるSSOサービスはありますか

.. などなど。

方程式には多くの変数があるので、これで物事が少しクリアされることを願っています。

9
toske

APIベースのAPPがクライアントである場合、APIには、サーバー応答ストリームからCookieを取得/読み取りして保存するオプションが必要です。同じサーバー/ URLのリクエストオブジェクトの準備中にCookieを自動的に追加します。利用できない場合、セッションIDは取得できません。

1
Bharath

各リクエストで何らかのトークンを送信することをお勧めします。

サーバーとサービスに応じて、これらはGET/POSTリクエストの [〜#〜] jsessionid [〜#〜] パラメーターまたは [〜#〜] saml [ 〜#〜] in SOAP Webサービス要求のHTTP経由。

1
iga

そうですね、標準的な環境で物事が「自動」である理由は、CookieがURL伝播よりもユーザーに見栄えをよくするために優先されるためです。つまり、ブラウザ(クライアントソフトウェア)は、すべてのリクエストとともにセッションCookieの保存と送信を管理します。

APIの世界では、単純なシステムでは、多くの場合、すべての要求とと​​もに(少なくとも私の作業では)認証資格情報が渡されます。クライアントの作成者は、通常(私の経験でも)Cookieストレージを実装することに消極的であり、すべての要求と一般的に最低限以上の送信を行います...

HTTPベースのAPI、カップルに名前を付けるHTTPベーシック/ダイジェスト、そしてもちろん私が間違えない場合にこれらのことに特化して設計されたユビキタスo-authには、他にも多くの認証メカニズムがあります。 Cookieは保持されず、資格情報はすべての交換の一部です(そのことについてはかなり確かです)。

もう1つ考慮すべきことは、APIでサーバー上のセッションを使用して何を行うかです。 Webサイト上のセッションは、現在のユーザーにストレージを提供し、通常、ページからページへのdbの負荷を軽減するために少量のデータを保存します。 APIコンテキストでは、状況が多かれ少なかれステートレスであるため、これはほとんど必要ありません。それは本当にサービスが何をしているかに依存します。

1
quickshiftin