開発履歴
1. 昔、Web は基本的にドキュメントを閲覧するだけでした。ブラウジングでは、サーバーとして、一定期間内に誰がどのドキュメントを閲覧したかを記録する必要はありません。各リクエストは、リクエストとレスポンスである新しい HTTP プロトコルです。特に、誰が閲覧したかを覚えておく必要はありません。 HTTP リクエストを送信しました すべてのリクエスト どちらのリクエストも私にとっては初めてです。とてもエキサイティングな時期です。
2. しかし、オンライン ショッピング Web サイトやログインが必要な Web サイトなどの対話型 Web アプリケーションの台頭により、すぐに問題に直面します。つまり、セッションを管理するには、誰がログを記録したかを覚えておく必要があります。誰がショッピング カートに商品を入れるか、つまり、各人を区別する必要がありますが、これは大きな課題です。HTTP リクエストはステートレスであるため、私が思いついた解決策は、全員にセッションを送信することです。 ID. (セッション ID) は、率直に言って、ランダムな文字列です。受け取り方は人それぞれです。私に HTTP リクエストを送信するたびに、この文字列も一緒に送信してください。そうすれば、私はそれを区別できます。誰が誰ですか?
3. 全員がとても満足していますが、サーバーは満足していません。全員が自分のセッション ID を保存するだけでよく、サーバーは全員のセッション ID を保存する必要があります。アクセス サーバーが多すぎる場合は、数千、場合によっては数十万ものアクセス サーバーが存在することになります。
これはサーバーにとって大きなオーバーヘッドであり、サーバーの拡張機能が大幅に制限されます。たとえば、2 台のマシンを使用してクラスターを形成し、Xiao F がマシン A を通じてシステムにログインすると、セッション IDマシン A で、Little F の次のリクエストがマシン B に転送されたらどうなるでしょうか?マシン B には小さな F のセッション ID がありません。
時々、ちょっとしたトリックが使用されます: セッション スティッキー、つまり Xiao F のリクエストが常にマシン A でスタックされることを意味しますが、これは機能しません。マシン A がハングアップした場合は、マシン B に転送する必要があります。 . .
次に、セッションをコピーする必要があります。2 台のマシン間でセッション ID を移動するのは、ほとんど骨の折れる作業です。
その後、Memcached という人が、セッション ID を 1 か所に集中的に保存し、すべてのマシンがこの場所のデータにアクセスするというトリックを思いつきました。コピーする必要はありませんが、単一障害点が発生する可能性が高くなります。セッションを担当するマシンがハングアップすると、全員が再度ログインする必要があり、おそらく死ぬほど叱られるでしょう。
また、信頼性を高めるためにこの 1 台のマシンをクラスターに入れようとしましたが、いずれにしても、この小さなセッションは私にとって大きな負担です。
4. それで、なぜこの忌まわしいセッションを保存しなければならないのかと考えている人もいるでしょう? 各クライアントに保存させておけばどれほど良いでしょうか?
しかし、これらのセッション ID が保存されていない場合、クライアントから送信されたセッション ID が実際に自分によって生成されたものであることをどのように確認すればよいでしょうか?確認しないと、正規のログインユーザーかどうかが分からず、悪意のあるユーザーがセッションIDを偽造してやりたい放題になる可能性があります。
さて、肝心なのは検証です!
たとえば、Little F がシステムにログインしたので、Little F のユーザー ID を含むトークンを彼に送信します。次に Little F が再び HTTP 経由で私へのアクセスを要求したときに、私は彼にトークンを送信します。トークン。このトークンは、HTTP ヘッダーを通じて持ち込むことができます。
ただし、セッション ID と本質的な違いはなく、誰でも偽造できるため、他人が偽造できないようにする方法を考える必要があります。
次に、データに署名を作成します。たとえば、HMAC-SHA256 アルゴリズムを使用し、自分だけが知っているキーを追加して、データに署名を作成し、この署名とデータをトークンとして使用します。 . 他人は鍵を知らないため、トークンを偽造することはできません。
関連する推奨事項: 「Python ビデオ チュートリアル」
このトークンは保存しません。Xiao F がこのトークンを送ってきたとき私が戻ってきたら、同じ HMAC-SHA256 アルゴリズムと同じキーを使用してデータの署名を再度計算し、トークン内の署名と比較します。それらが同じであれば、Xiao F がログインしていることがわかります。違う場合はデータ部分が改ざんされているはずですので、送信者に「申し訳ありませんが、認証はありません」と伝えておきます。
#トークン内のデータはクリア テキストで保存されます (エンコードには Base64 を使用しますが、これは暗号化ではありません)。他の人が見ることができます。できません。パスワードなどの機密情報を保存してください。
もちろん、トークンが他人に盗まれてしまったら、どうすることもできません。また、盗んだ人は正規のユーザーだと思います。これは、実際には、人のセッション ID が盗まれるのと同じです。その他。
この方法では、セッション ID を保存しません。トークンを生成してからトークンを検証するだけです。CPU コンピューティング時間を使用してセッション ストレージ スペースを取得します。
セッション ID の負担が軽減されました。することがなくなったと言えます。マシン クラスタを簡単に水平拡張できるようになりました。ユーザーのアクセス数が増えてきたら、マシンを直接追加するだけで済みます。この無国籍感がとても良い!
Cookie
Cookie は非常に特殊なもので、ブラウザーに永続的に保存できる一種のデータを指します。実装されたデータの一種にすぎません。ブラウザによるストレージ機能です。
Cookie はサーバーによって生成され、ブラウザに送信されます。ブラウザは、Cookie を kv 形式で特定のディレクトリ内のテキスト ファイルに保存します。Cookie は、次回同じ Web サイトを訪問するときにサーバーに送信されます。と要求される。 Cookie はクライアントに保存されるため、Cookie が悪意を持って使用されたり、ディスク領域を占有しすぎたりしないように、ブラウザにはいくつかの制限が追加されているため、各ドメインの Cookie の数は制限されています。
セッション
セッション 文字通り、これはセッションです。これは、誰かと話しているときと似ていますが、話している相手が李斯ではなく張三であることがどうしてわかるのでしょうか?相手は張三であることを示す何らかの特徴(外見など)を持っている必要があります。
session も同様ですが、サーバーは現在誰が自分自身にリクエストを送信しているかを知る必要があります。この区別を行うために、サーバーは各クライアントに異なる「アイデンティティ識別子」を割り当てます。その後、クライアントがサーバーにリクエストを送信するたびに、この「アイデンティティ識別子」が提供され、サーバーはリクエストが誰からのものであるかを認識します。 。クライアントがこの「ID」を保存する方法については、さまざまな方法がありますが、ブラウザ クライアントの場合は、デフォルトで Cookie が使用されます。
サーバーはセッションを使用してユーザーの情報をサーバーに一時的に保存します。ユーザーが Web サイトを離れるとセッションは破棄されます。ユーザー情報を保存するこの方法は Cookie よりも安全ですが、セッションには欠陥があります。Web サーバーが負荷分散されている場合、次の操作リクエストが別のサーバーに送信されるとセッションが失われます。
トークン
トークンベースの認証は、Web 分野のいたるところで見られます。 Web API を使用するほとんどのインターネット企業では、トークンが複数のユーザーの認証を処理する最適な方法です。
次の機能により、プログラムでトークンベースの認証を使用できるようになります:
(1) ステートレスで拡張可能
(2) モバイル デバイスのサポート
(3) プログラム間呼び出し
(4) セキュリティ
トークンベースの認証を使用する大手企業、これまでに見た API や Web アプリケーションのほとんどはすべてトークンを使用しています。たとえば、Facebook、Twitter、Google、GitHub などです。
トークンの起源
トークンベースの認証の原理と利点を紹介する前に、以前の認証がどのように行われていたかを見てみるのもよいでしょう。
サーバーベースの検証
HTTP プロトコルがステートレスであることは誰もが知っていますが、このステートレス性は、プログラムがクライアントの ID を識別するために各リクエストを検証する必要があることを意味します。
これに先立って、プログラムはサーバーに保存されているログイン情報を通じてリクエストを識別しました。この方法は通常、セッションを保存することによって実現されます。
Web、アプリケーション、モバイル端末の台頭により、この検証方法の問題点が徐々に明らかになってきました。特にスケーラビリティに関してはそうです。
サーバー認証方法に基づいて明らかにされるいくつかの問題
(1) セッション: 認証されたユーザーがリクエストを開始するたびに、サーバーは情報を保存するためのレコードを作成する必要があります。 。リクエストを送信するユーザーが増えると、メモリのオーバーヘッドが増加し続けます。
(2) スケーラビリティ: セッションを使用してサーバーのメモリにログイン情報を保存すると、スケーラビリティの問題が発生します。
(3) CORS (クロスオリジン リソース共有): 複数のモバイル デバイス間でデータを使用する必要がある場合、クロスドメイン リソースの共有が問題になることがあります。 Ajax を使用して別のドメインからリソースをクロールする場合、リクエストが禁止される場合があります。
(4) CSRF (クロスサイト リクエスト フォージェリ): ユーザーが銀行 Web サイトにアクセスすると、クロスサイト リクエスト フォージェリ攻撃に対して脆弱になり、他の Web サイトへのアクセスに悪用される可能性があります。
これらの問題の中で、スケーラビリティが最も顕著です。したがって、より効果的な方法を見つける必要があります。
トークンベースの認証原理
トークンベースの認証はステートレスであり、ユーザー情報はサーバーまたはセッションに保存されません。
この概念は、サーバー側に情報を保存する際の多くの問題を解決します。
NoSession は、ユーザーがログインしているかどうかを気にすることなく、プログラムが必要に応じてマシンを追加または削除できることを意味します。
トークンベースの認証のプロセスは次のとおりです。
(1) ユーザーは、ユーザー名とパスワードを使用してリクエストを送信します。
(2) プログラムの検証。
(3) プログラムは署名付きトークンをクライアントに返します。
(4) クライアントはトークンを保存し、リクエストごとにそれを使用します。
(5) サーバーはトークンを検証し、データを返します。
すべてのリクエストにはトークンが必要です。 HTTP リクエストがステートレスであることを保証するには、トークンを HTTP ヘッダーで送信する必要があります。また、サーバー プロパティ Access-Control-Allow-Origin:* を設定して、サーバーがすべてのドメインからのリクエストを受け入れることができるようにします。
ACAOヘッダーに*を付ける(指定する)場合、HTTP認証、クライアントSSL証明書、Cookieなどの証明書を含めてはいけないことに注意してください。
実装アイデア:
(1) ユーザーのログイン検証: 検証が成功すると、トークンがクライアントに返されます。
(2) クライアントはデータを受信後、クライアント上にデータを保存します。
(3) クライアントは API にアクセスするたびにトークンをサーバーに渡します。
(4) サーバー側ではフィルターフィルター検証を使用します。検証が成功した場合はリクエストデータが返され、検証が失敗した場合はエラーコードが返されます。プログラム内の情報を認証してトークンを取得すると、このトークンを使用してさまざまなことができるようになります。許可ベースのトークンを作成し、それをサードパーティのアプリケーションに渡して、データを取得することもできます (許可されている特定のトークンを使用する場合のみ)。
トークンの利点
ステートレスでスケーラブル
トークンはクライアント側に保存されます。ステートレスで拡張可能。このステートレス性とセッション情報の保存がないことに基づいて、ロード バランサーはユーザー情報を 1 つのサービスから他のサーバーに転送できます。
認証されたユーザーの情報をセッションに保存する場合、各リクエストでは、ユーザーは認証されたサーバーに認証情報を送信する必要があります (セッション アフィニティと呼ばれます)。利用者が多い場合は混雑が発生する場合がございます。
しかし、急ぐ必要はありません。トークンを使用すると、トークン自体にユーザーの検証情報が保持されるため、これらの問題は簡単に解決されます。
セキュリティ
リクエストで Cookie の代わりにトークンを送信すると、CSRF (クロスサイト リクエスト フォージェリ) を防ぐことができます。クライアント上でトークンを保存するために Cookie が使用されている場合でも、Cookie は単なる保存メカニズムであり、認証には使用されません。セッションに情報を保存しないことで、操作するセッションの数を減らすことができます。
トークンには期限があり、ユーザーは一定期間後に再検証する必要があります。トークンの有効期限が自動的に切れるまで必ずしも待つ必要はありません。トークンには引き出し操作があり、トークンの取り消しを通じて、特定のトークンまたは同じ認証を持つトークンのグループを無効にすることができます。
拡張性
トークンを使用すると、他のプログラムとアクセス許可を共有するプログラムを作成できます。たとえば、ランダムなソーシャル アカウントを自分のアカウント (Fackbook または Twitter) に接続できます。サービスを通じて Twitter にログインするとき (このプロセスをバッファーします)、これらのバッファーを Twitter データ ストリームに添付できます (バッファーが Twitter ストリームに投稿できるようにします)。
トークンを使用する場合、オプションの権限をサードパーティのアプリケーションに提供できます。ユーザーが別のアプリケーションに自分のデータにアクセスしてもらいたい場合、独自の API を構築することで特別な許可トークンを取得できます。
マルチプラットフォーム クロスドメイン
CORS (クロスドメイン リソース共有) について事前に説明しておきますが、アプリケーションやサービスを拡張する際には、さまざまな要素に介入する必要があります。さまざまなデバイスとアプリケーション。
Having our API just serve data, we can also make the design choice to serve assets from a CDN. This eliminates the issues that CORS brings up after we set a quick header configuration for our application.
ユーザーが検証済みのトークンを持っている限り、どのドメインでもデータとリソースをリクエストできます。
Access-Control-Allow-Origin: *
標準に基づいてトークンを作成する場合、いくつかのオプションを設定できます。詳細については後続の記事で説明しますが、標準的な使用法は JSON Web トークンに反映されます。
JSON Web トークン用の最新のプログラムとドキュメントが提供されています。多数の言語をサポートしています。これは、将来的に認証メカニズムを実際に切り替えることができることを意味します。
以上がCookie、セッション、トークンを 1 つの記事で徹底的に理解するの詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。