トークン認証とCookie


141

トークン認証とCookieを使用した認証の違いは何ですか?

Ember Auth Railsデモを実装しようとしていますが、「なぜトークン認証なのか」という質問のEmber Auth FAQに記載されているように、トークン認証を使用する背後にある理由がわかりません。


4
トークンは、モバイルアプリに付与して、後で使用するために(ユーザーが)変数に格納するか、SPAリクエストで使用するためにブラウザーでJavaScriptを介して(ユーザーが)保存できます。Cookieは通常、ブラウザーで(ブラウザーによって)使用されます。
Tino Mclaren、2015

回答:


34

典型的なWebアプリは、リクエスト/レスポンスの性質上、ほとんどステートレスです。HTTPプロトコルは、ステートレスプロトコルの最良の例です。しかし、ほとんどのWebアプリは状態を必要とするため、サーバーとクライアントの間で状態を保持するために、サーバーがすべての応答をクライアントに送信できるようにCookieが使用されます。つまり、クライアントからの次の要求にはこのCookieが含まれているため、サーバーによって認識されます。このようにして、サーバーはステートレスクライアントとのセッションを維持でき、アプリの状態に関するほとんどすべてを知っていますが、サーバーに保存されます。このシナリオでは、クライアントは保持しません状態方法ではありません、Ember.jsが動作します。

Ember.jsでは状況が異なります。それは確かに保持しているためEmber.jsが容易プログラマの仕事になり状態をあなたのためにそれのほぼすべての瞬間に知って、クライアントでは、状態を求めてサーバにリクエスト加えることなく、状態データを。

しかし、保持状態をクライアントにすることも時々では、単に存在しない並行性の問題を導入することができますステートレスな状況を。ただし、Ember.jsはこの問題にも対処します。具体的には、ember-dataはこれを念頭に置いて構築されています。結論として、Ember.jsはステートフルクライアント用に設計されたフレームワークです。

Ember.jsは、セッション状態、および対応するCookieがサーバーによってほぼ完全に処理される典型的なステートレス Webアプリのようには機能しません。Ember.jsはその状態を完全にJavaScriptで保持し(クライアントのメモリ内であり、他のいくつかのフレームワークのようなDOMではありません)、セッションを管理するためにサーバーを必要としません。これにより、アプリがオフラインモードのときなど、多くの状況でEmber.jsの用途が広がります。

明らかにセキュリティ上の理由から、認証を受けるためにリクエストが行われるたびにサーバーに送信するある種のトークンまたは一意のキーが必要です。これにより、サーバーは送信トークン(サーバーによって最初に発行された)を検索できます。クライアントに応答を返す前に、それが有効かどうかを確認してください。

私の意見では、Ember Auth FAQで述べられているようにCookieの代わりに認証トークンを使用する主な理由は、主にEmber.jsフレームワークの性質と、ステートフルな Webアプリパラダイムにより適合するためです。したがって、Ember.jsアプリを構築する場合、Cookieメカニズムは最適なアプローチではありません。

私の回答があなたの質問により多くの意味を与えることを願っています。


84
トークンがCookieよりも優れている/異なる理由がまだわかりません。何らかの方法で、有効なセッションを識別する何かをAPIサーバーに送信しています。単一のドメインですべてを実行していると仮定します(emberとapiが異なるサーバー上にある場合でも、これを達成するために実行する必要があるのはcdnの背後で実行されるため、とにかく実行する必要があります)トークンが提供する利点は、余分なセットアップ作業とタイミング攻撃の余計な脆弱性?
マイケルジョンストン

46
マイケル・ジョンストンに同意しました。この答えは、トークンベースの認証とは何かを説明し続けていますが、実際には質問には答えていません。私が見ることができる最も近い関連情報は最後のビットにあります。「ember.jsフレームワークの性質のため、またそれはステートフルなWebアプリパラダイムにより適しているため」ですが、それはまったく答えにはなりません。同じ質問があります。
ダニエル

5
私はここの両方のコメントに同意します...実際、私は全体として「それは燃えさしの道だ」とは少し
警戒心が強いと感じ

3
正直なところ、ステートフルネスは、他の方法で送信されたCookieとトークンではなく、ニシンだと思います。ユーザーの証拠の概念を他のユーザープロファイル情報と統合していると思います。トークンを送信するために、HTTPヘッダーまたは他のチャネルとまったく同じCookieを使用できます。違いは、Cookieの単一オリジンポリシーに関連する問題を回避したり、バックエンドのネイティブクライアントからCookieコンテナーを実装する負担を取り除いたりすることに関するものだと思います。
Michael Lang

15
ember.jsは、尋ねられた質問に焦点を当てて宣伝しないでください。失礼なことに申し訳ありません。
Vick_Pk 2017

336

Httpはステートレスです。承認するには、サーバーに送信するすべてのリクエストに「署名」する必要があります。

トークン認証

  • サーバーへのリクエストは「トークン」によって署名されます-通常、これは特定のhttpヘッダーを設定することを意味しますが、httpリクエストの任意の部分(POST本文など)で送信できます。

  • 長所:

    • 承認したいリクエストのみを承認できます。(Cookies-承認Cookieでさえ、すべてのリクエストに対して送信されます。)
    • XSRFの影響を受けない(XSRFの簡単な例-のようなリンクをメールで送信します<img src="http://bank.com?withdraw=1000&to=myself" />。bank.comへのcookie認証を介してログインしていて、bank.comにXSRFの手段がない場合保護のために、ブラウザーがそのURLへの許可されたGET要求をトリガーするという事実によって、アカウントからお金を引き出します。)Cookieベースの認証で実行できる偽造防止策がありますが、それらを実装する必要があります。
    • Cookieは単一のドメインにバインドされています。ドメインfoo.comで作成されたCookieは、ドメインbar.comで読み取ることはできませんが、トークンは任意のドメインに送信できます。これは、承認を必要とする複数のサービスを消費する単一ページアプリケーションに特に役立ちます。ドメインmyapp.comに、myservice1.comおよびmyservice2.comへの承認済みのクライアント側リクエストを作成できるWebアプリを作成できます。
  • 短所:
    • トークンはどこかに保存する必要があります。Cookieは「そのまま」保存されます。思い浮かぶ場所は、localStorage(con:ブラウザーウィンドウを閉じた後でもトークンが保持される)、sessionStorage(pro:ブラウザーウィンドウを閉じた後にトークンが破棄される、con:新しいタブでリンクを開くとそのタブがレンダリングされる)です。 anonymous)とcookie(Pro:ブラウザーウィンドウを閉じた後、トークンは破棄されます。セッションcookieを使用する場合、新しいタブでリンクを開くときに認証され、XSRFの影響を受けません。認証用のCookieは、トークンストレージとして使用しているだけです。Con:Cookieは、すべてのリクエストに対して送信されます。このCookieがhttpsとしてのみマークされていない場合は、中間者攻撃にさらされます。)
    • トークンベースの認証に対してXSS攻撃を実行する方が少し簡単です(つまり、サイトで挿入されたスクリプトを実行できれば、トークンを盗むことができます。ただし、Cookieベースの認証も特効薬ではありません。クライアントはhttp-onlyを読み取ることはできません。クライアントは、ユーザーに代わって、承認cookieを自動的に含めるリクエストを行うことができます。
    • 許可されたユーザーのみが機能するはずのファイルをダウンロードするリクエストでは、File APIを使用する必要があります。同じ要求がCookieベースの認証のすぐに使用できます。

クッキー認証

  • サーバーへのリクエストは常に認証Cookieによってサインインされます。
  • 長所:
    • Cookieを「httpのみ」としてマークすると、クライアント側で読み取ることができなくなります。これはXSS攻撃からの保護に適しています。
    • 箱から出して-クライアント側でコードを実装する必要はありません。
  • 短所:
    • 単一のドメインにバインドされています。(つまり、複数のサービスにリクエストを送信する単一ページのアプリケーションがある場合、リバースプロキシのようなクレイジーなことをしてしまう可能性があります。)
    • XSRFに対して脆弱です。クロスサイトリクエストフォージェリからサイトを保護するために、追加の対策を実装する必要があります。
    • リクエストごとに送信されます(認証を必要としないリクエストでも)。

全体として、トークンを使用すると柔軟性が向上すると思います(単一のドメインにバインドされていないため)。欠点は、自分でかなりのコーディングを行う必要があることです。


56
この回答は、受け入れられている回答よりも、正準回答にはるかに近いものです。
xlecoustillier 2016年

3
@ ondrej-svejdarに感謝します。断然ベストアンサーです!私は「かなりのコーディング」の部分でのみ議論します。ほとんどすべての言語で利用できるライブラリーは多数あります。したがって、JWT実装のメカニズムを本当に知りたいのでない限り、ゼロから始める必要はありません。
FullStackForger

2
Are send out for every single requestトークンはすべてのリクエストに対しても送信されます
Eugen Konkov '21

10
@EugenKonkov no。必要ではない。ヘッダーを追加する場合のみ。Cookieは、必要に応じて、または望まない場合にブラウザから送信されます
Royi Namir

2
@ザック-それは重要です。Cookieの問題は、ブラウザによってリクエストに自動的に追加されることです。一方、トークンはJavaScriptによってXHRリクエストに追加されます。evildomain.comがmysite.com(トークンを保存する場所としてローカルストレージをお勧めしません)またはram(ここではトークンを含むjavascript変数を意味すると想定)のローカルストレージにアクセスすることは不可能です。変数は別のブラウザーウィンドウでサンドボックス化されます。
Ondrej Svejdar 2017

34
  • トークンはどこかに保存する必要があります(ローカル/セッションストレージまたはCookie)

  • トークンはCookieのように期限切れになる可能性がありますが、より細かく制御できます

  • ローカル/セッションストレージはドメイン間で機能しません。マーカーCookieを使用してください

  • プリフライト要求は各CORS要求で送信されます

  • 何かをストリーミングする必要がある場合は、トークンを使用して署名付きリクエストを取得します

  • XSRFよりもXSSの方が扱いやすい

  • トークンはリクエストごとに送信されます。そのサイズに注意してください

  • 機密情報を保存する場合は、トークンを暗号化します

  • JSON Web TokenはOAuthで使用できます

  • トークンは特効薬ではありません。承認の使用例を慎重に検討してください

http://blog.auth0.com/2014/01/27/ten-things-you-should-know-about-tokens-and-cookies/

http://blog.auth0.com/2014/01/07/angularjs-authentication-with-cookies-vs-token/


14
ポイントがCookieとトークンのどちらであるかは明確ではありません。
Pureferret、2015

6
どうしてあなたがクッキーよりもトークンを「よりコントロール」するのか理解できません。
アーロン

@onsmith私が理解していることから、ここには1つ以上の箇条書きがあります。まず、Cookieはリクエストごとに送信されます。トークンの送信は、JavaScriptコードによってトリガーされます。自動的には送信されません。また、rfcセクション4によれば、JWTはパーティ間でセキュリティ要求を転送するために使用されるコンテナとして設計されているように見えます。これにより、よりきめ細かい制御が可能になるだけでなく、サードパーティの認証トークンを生成して、ユーザーに代わって使用できるようにする一連の権限を付与できます。
FullStackForger

17

Google社員向け

  • ステートフル性ステート転送メカニズムを混在させないでください

ステートフルネス

  • ステートフル =サーバー側で認証情報を保存します。これは従来の方法です
  • ステートレス =クライアント側で承認情報を保存し、署名とともに整合性を確保します

メカニズム

  • Cookie =ブラウザによる特別な処理(アクセス、保存、有効期限、セキュリティ、自動転送)を備えた特別なヘッダー
  • カスタムヘッダー =たとえばAuthorization、ヘッダーは特別な処理なしで、クライアントは転送のすべての側面を管理する必要があります
  • その他。他の転送メカニズムを利用することもできます。たとえば、クエリ文字列はしばらくの間認証IDを転送するための選択でしたが、その不安のために放棄されました

ステートフルネス比較

  • 「ステートフル認証」とは、サーバーがユーザー認証情報をサーバーに保存および維持し、認証をアプリケーション状態の一部にすることを意味します
  • つまり、クライアントは「認証ID」を保持するだけでよく、サーバーはデータベースから認証の詳細を読み取ることができます。
  • これは、サーバーがアクティブな認証(ログインしているユーザー)のプールを保持し、すべてのリクエストに対してこの情報をクエリすることを意味します
  • 「ステートレス認証」とは、サーバーがユーザー認証情報を保存および維持せず、どのユーザーがサインインしているかを認識せず、クライアントに依存して認証情報を生成することを意味します
  • クライアントは、あなたが誰であるかなどの完全な認証情報(ユーザーID)を保存し、許可、有効期限なども保存します。これは単なる認証IDではなく、新しい名前トークンが与えられます。
  • 明らかにクライアントは信頼できないため、認証データはから生成された署名とともに保存さhash(data + secret key)れます。この場合、秘密鍵はサーバーだけが知っているため、トークンデータの整合性を確認できます
  • トークンメカニズムは完全性を保証するだけで、機密性は保証しません。クライアントはそれを実装する必要があります。
  • これは、すべてのリクエストに対して、クライアントが完全なトークンを送信する必要があることを意味し、追加の帯域幅が発生します

メカニズムの比較

  • 「Cookie」は単なるヘッダーですが、ブラウザでいくつかのプリロードされた操作があります
  • Cookieはサーバーによって設定され、クライアントによって自動保存され、同じドメインに自動送信されます
  • Cookieにマークを付けることがhttpOnlyできるため、クライアントのJavaScriptアクセスを防止できます
  • プリロードされた操作は、ブラウザー以外のプラットフォーム(モバイルなど)では使用できない場合があり、追加の作業が必要になる場合があります
  • 「カスタムヘッダー」は、プリロードされた操作のない単なるカスタムヘッダーです
  • クライアントは、各リクエストのカスタムヘッダーセクションを受信、保存、保護、送信、および更新する責任があります。これにより、単純な悪意のあるURLの埋め込みを防ぐことができます。

まとめ

  • 魔法はありません、認証状態はサーバーまたはクライアントのどこかに保存する必要があります
  • Cookieまたはその他のカスタムヘッダーを使用してステートフル/ステートレスを実装できます
  • 人々がそれらのことについて話すとき、彼らのデフォルトの考え方は主に次のとおりです:ステートレス=トークン+カスタムヘッダー、ステートフル=認証ID +クッキー。これらは唯一の可能なオプションではありません
  • 彼らには長所と短所がありますが、暗号化されたトークンであっても機密情報を保存しないでください

リンク


1
本当にありがとうございました。質問に回答し、突然他の回答から生成されたすべての混乱がステートフル性について突然話します。
MDave

とてもとても良い。詳細を表示し、方法と理由をより適切に説明します。
コリンウォン

8

ここには混乱があると思います。Cookieベースの認証とHTML5 Web Storageで現在可能になっている認証との大きな違いは、ブラウザーは、Cookieデータを設定したドメインからリソースを要求するときはいつでも、Cookieデータを送信するように構築されていることです。クッキーをオフにしないと、それを防ぐことはできません。ブラウザは、ページ内のコードがデータを送信しない限り、Web Storageからデータを送信しません。また、ページは、他のページが保存したデータではなく、保存したデータにのみアクセスできます。

したがって、ユーザーが自分のCookieデータがGoogleまたはFacebookで使用される可能性があることを心配して、Cookieをオフにする場合があります。ただし、Webストレージをオフにする理由はあまりありません(広告主がWebストレージを使用する方法を見つけるまで)。

つまり、Cookieベースとトークンベースの違いです。後者はWeb Storageを使用しています。


5

トークンベースの認証はステートレスであり、サーバーはセッションにユーザー情報を保存する必要はありません。これにより、ユーザーがどこにログインしたかを気にせずにアプリケーションをスケーリングできます。CookieベースのWebサーバーフレームワークアフィニティがありますが、トークンベースの問題ではありません。そのため、同じトークンを使用して、ログインしているドメイン以外のドメインから安全なリソースを取得できます。これにより、別のuid / pwd認証が回避されます。

ここに非常に良い記事:

http://www.toptal.com/web/cookie-free-authentication-with-json-web-tokens-an-example-in-laravel-and-angularjs


3

トークンを使用する...

連合が望ましい。たとえば、1つのプロバイダー(Token Dispensor)をトークン発行者として使用し、次にAPIサーバーをトークン検証ツールとして使用するとします。アプリはToken Dispensorに対して認証を行い、トークンを受け取り、そのトークンをAPIサーバーに提示して検証することができます。(Googleサインイン、Paypal、Salesforce.comなどでも同様に機能します)

非同期性が必要です。たとえば、クライアントがリクエストを送信し、そのリクエストをどこかに保存して、「後で」別のシステムが処理するようにしたいとします。その別個のシステムはクライアントへの同期接続がなく、中央のトークンディスペンサリーへの直接接続がない場合があります。非同期処理システムがJWTを読み取って、後で作業項目を実行できるかどうか、および実行する必要があるかどうかを判断できます。これは、ある意味で、上記のフェデレーションのアイデアに関連しています。ただし、ここで注意してください。JWTの有効期限が切れます。作業項目を保持するキューがJWTの存続期間内に処理されない場合、クレームは信頼されなくなります。

署名済みのリクエストが必要です。ここでは、要求はクライアントの秘密鍵を使用して署名され、サーバーはクライアントの登録済みの公開鍵を使用して検証します。


1

主な違いの1つは、Cookieが同一生成元ポリシーの対象であるのに対し、トークンは対象外であることです。これにより、あらゆる種類のダウンストリームエフェクトが作成されます。

Cookieは特定のホストとの間でのみ送信されるため、そのホストはユーザーを認証する負担を負う必要があり、ユーザーは検証できるようにそのホストでセキュリティデータを含むアカウントを作成する必要があります。

一方、トークンは発行され、同じ生成元ポリシーの対象ではありません。発行者は文字通り誰でもかまいません。どの発行者を信頼するかはホストが決定します。GoogleやFacebookのような発行者は通常、十分に信頼されているため、ホストはユーザー認証の負担(すべてのユーザーセキュリティデータの保存を含む)を別の当事者に移すことができ、ユーザーは特定の発行者の下で個人データを統合でき、覚えておく必要はありません。対話するホストごとに異なるパスワードの束。

これにより、ユーザーエクスペリエンスの全体的な摩擦を軽減するシングルサインオンシナリオが可能になります。理論的には、すべてのmaとpaのWebサイトが独自の、おそらく半分焼きたての認証システムを起動する代わりに、専門のIDプロバイダーが認証サービスを提供するようになると、Webはより安全になります。そして、これらのプロバイダーが出現すると、非常に基本的なリソースでさえゼロに向かう傾向に対して、安全なWebリソースを提供するコストが発生します。

したがって、一般的にトークンは、認証の提供に関連する摩擦とコストを削減し、セキュリティで保護されたWebのさまざまな側面の負担を、セキュリティシステムの実装と保守の両方をより効率的に行える中央の当事者に移します。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.