##関連トピックの推奨事項: php cookie (トピック)
セッションとは
セッションとは別のメカニズムですサーバーとクライアントのセッション ステータスを記録するための ##セッションは Cookie に基づいて実装されます。セッションはサーバー側に保存され、sessionId はクライアントの Cookie に保存されます
セッション認証プロセス:
ユーザーが初めてサーバーを要求すると、サーバーは、対応するセッションを作成します。
リクエストが返されたときに、このセッションの一意の識別情報であるセッション ID をブラウザに返します。
ブラウザは、サーバーから返されたセッション ID 情報を受信した後、この情報は Cookie に保存され、Cookie はこの SessionID がどのドメイン名に属しているかを記録します
ユーザーがサーバーに 2 度目にアクセスすると、リクエストはこのドメイン名の下に Cookie 情報があるかどうかを自動的に判断します。 Cookie 情報がある場合は、Cookie 情報もサーバーに自動的に送信されます。サーバーは Cookie から SessionID を取得し、SessionID に基づいて該当するセッション情報を検索します。見つからない場合は、ユーザーがログインしていないか、ログインが無効です。セッションが見つかった場合は、ユーザーがログインしていることが証明され、次の操作を実行できます。
上記のプロセスによれば、 SessionID は Cookie とセッション を接続するブリッジであり、ほとんどのシステムはこの原則を使用してユーザーのログイン ステータスを確認します。
関連トピックの推奨事項: php セッション セッション (トピック)
Cookie とセッションの違い
セキュリティ: セッションは Cookie よりも安全です。セッションはサーバー側に保存され、Cookie はサーバー側に保存されます。クライアント側。
さまざまな種類のアクセス値 : Cookie は文字列データの保存のみをサポートしています。他の種類のデータを設定したい場合は、文字列に変換する必要があります。セッションは任意のデータ型を保存できます。
さまざまな有効期間: Cookie は、よく使用するデフォルトのログイン機能など、長期間保持されるように設定できます。セッションの有効期限は一般的に短く、クライアントは閉じられています。 (デフォルト) またはセッションがタイムアウトすると、すべて失敗します。
さまざまなストレージ サイズ: 1 つの Cookie によって保存されるデータは 4K を超えることはできません。セッションは Cookie よりも多くのデータを保存できますが、アクセス数が多すぎると、多くのサーバーを占有します。リソース。
#トークンとは アクセス トークン
##リソース インターフェイス (API) にアクセスするために必要なリソース認証情報 単純なトークンの構成: uid (ユーザーの一意の ID)、time (現在の時刻のタイムスタンプ)、sign (署名、トークンの最初の数桁はハッシュ アルゴリズムで圧縮されます)特定の長さの 16 進文字列)
特徴:
サーバーはステートレスであり、優れたスケーラビリティを備えています モバイル デバイスのサポート
セキュリティ
プログラム間呼び出しのサポート
トークン認証プロセス:
クライアントはユーザー名とパスワードを使用してログインをリクエストします。
サーバーはリクエストを受信し、ユーザー名とパスワードを検証します 検証が成功した後、サーバーはトークンを発行し、クライアントにトークンを送信します。
クライアントがトークンを受信すると、それを Cookie や localStorage などに保存します。 クライアントはサーバーからリソースを要求するたびに、サーバーによって発行されたトークンを取得する必要がありますサーバーは要求を受信し、検証が成功した場合はクライアント要求にトークンが含まれていることを検証します。 、リクエストされたデータはクライアントに返されます
すべてのリクエストはトークンを運ぶ必要があり、トークンは HTTP ヘッダーに配置される必要があります トークンベースのユーザー認証はサーバー側のステートレス認証方法であり、サーバーはトークン データを保存する必要がありません。トークンの解析の計算時間はセッションのストレージ領域と交換されるため、サーバーへの負荷が軽減され、データベースへの頻繁なクエリが削減されます。
トークンは、によって完全に管理されます。これにより、同一生成元ポリシーを回避できます
リフレッシュ トークン
別の種類のトークン—リフレッシュ トークン
リフレッシュ トークンは、アクセス トークンをリフレッシュするために特に使用されるトークンです。リフレッシュトークンがない場合は、アクセストークンをリフレッシュすることもできますが、リフレッシュのたびにログインユーザー名とパスワードを入力する必要があり、非常に手間がかかります。リフレッシュトークンを使用すると、クライアント側で直接リフレッシュトークンを使用してアクセストークンを更新することができ、ユーザーに追加の操作をさせることなく、この手間を軽減できます。
#アクセス トークンの有効期限は比較的短いため、期限切れによりアクセス トークンが無効になった場合は、更新を使用できます。新しいトークンを取得するには、リフレッシュ トークンの有効期限が切れた場合、ユーザーは再度ログインすることしかできません。 リフレッシュ トークンと有効期限はサーバー データベースに保存され、新しいアクセス トークンを申請するときにのみ検証されます。ビジネス インターフェイスの応答時間には影響せず、サーバー データベースに保存する必要はありません。セッションと同じ状態をメモリ内に保持して、大量のリクエストを処理します。
トークンとセッションの違い
セッションは、サーバーとクライアントのセッション ステータスを記録する メカニズムであり、サーバーをステートフルにし、記録できるようにします。セッション情報。そして、トークンは Token、 リソース インターフェイス (API) にアクセスするために必要なリソース資格情報 です。トークン はサーバーをステートレスにし、セッション情報を保存しません。
セッションとトークンは矛盾しません。ID 認証トークンとしては、各リクエストが署名されており、監視やリプレイ攻撃を防ぐことができるため、セキュリティはセッションよりも優れていますが、セッションはリンク層に依存する必要があります。 . 通信のセキュリティを確保するため。 ステートフル セッションを実装する必要がある場合でも、セッションを追加してサーバー側に一部の状態を保存できます。
いわゆるセッション認証は、ユーザー情報をセッションに保存するだけであり、SessionID が予測できないため、当面は安全であると考えられています。また、トークン (OAuth トークンまたは同様のメカニズムを指す場合) は、認証と認可を提供します。認証はユーザーに対して、認可はアプリに対して行われます。その目的は、アプリにユーザーの情報にアクセスする権利を与えることです。ここのトークンはユニークです。他のアプリや他のユーザーに転送することはできません。セッションは単純な認証のみを提供します。つまり、このセッション ID がある限り、このユーザーはすべての権限を持っていると見なされます。このデータは極秘に保管する必要があり、このデータはサイト上にのみ保存されるべきであり、他の Web サイトやサードパーティのアプリと共有すべきではありません。簡単に言えば: ユーザー データを第三者と共有する必要がある場合、または第三者による API インターフェイスの呼び出しを許可する必要がある場合は、トークンを使用します。常に自分の Web サイトと自分のアプリだけであれば、何を使用するかは問題ではありません。
JWT とは
JSON Web トークン (略して JWT) は、現在最も人気のある クロスドメイン認証 ソリューションです。
は 認証および認可メカニズム です。
JWT は、ネットワーク アプリケーション環境間で transfer ステートメント を行うために実装された JSON ベースのオープン標準 (RFC 7519) です。 JWT クレームは通常、リソース サーバーからリソースを取得するために、アイデンティティ プロバイダーとサービス プロバイダーの間で認証されたユーザー ID 情報を渡すために使用されます。たとえば、ユーザーのログインに使用されます。
HMAC アルゴリズムまたは RSA 公開/秘密キーを使用して JWT に署名できます。デジタル署名が存在するため、送信される情報には信頼性があります。
Ruan Yifeng 先生による JSON Web Token の入門チュートリアルは非常にわかりやすいので、ここでは詳細は説明しません
JWT の生成 jwt.io/www.jsonwebtoken.io/
JWT の原則
JWT 認証プロセス:
ユーザーはユーザー名/パスワードを入力してログインし、サーバーにログインします。認証が成功すると、JWT がクライアントに返されます。
クライアントはトークンをローカルに保存します (通常はローカルストレージが使用されますが、Cookie も使用できます)
ユーザーが保護されたルートまたはリソースを要求するときは、ベアラー モードを使用してリクエスト ヘッダーの Authorization フィールドに JWT を追加する必要があります。その内容は次のとおりです。 #サーバー側で保護されたルーティングがチェックされます リクエスト ヘッダーの JWT 情報 認可が有効であれば、ユーザーの動作が許可されます
JWT は自己完結型 (セッション情報が含まれている) であるため、必要性が軽減されますデータベースにクエリを実行します JWT は Cookie を使用しないため、クロスドメイン リソース共有 (CORS) を気にすることなく、任意のドメイン名を使用して API サービスを提供できます。
ユーザーのステータスは次のとおりです。サーバーのメモリには保存されないため、これはステートレスな認証メカニズムです
JWT の使用方法
クライアントはサーバーから返された JWT を受け取ります。 Cookie に保存されるか、localStorage に保存されます。
ユーザーが保護されたルートまたはリソースにアクセスしたい場合は、それを Cookie に入れて自動的に送信できますが、これはドメインを越えることができないため、より良い方法は、それを Cookie に入れることです。 HTTP リクエスト ヘッダー。メッセージの Authorization フィールドに、ベアラー モードを使用して JWT を追加します。
Authorization: Bearer <token>复制代码</token>
ユーザーのステータスはサーバーのメモリに保存されません。これは ステートレス認証メカニズムです
サーバーの保護ルートがチェックされます JWT 情報Authorization リクエスト ヘッダー内で有効であれば、ユーザーの動作が許可されます。
JWT は自己完結型であるため、データベースにクエリを実行する必要性が減ります。 JWT のこれらの機能により、JWT のステートレス機能に完全に依存してデータ API サービスを提供したり、ストリーミング サービスをダウンロードします。
JWT は Cookie を使用しないため、クロスドメインのリソース共有について心配する必要なく、任意のドメイン名を使用して API サービスを提供できます (CORS)
方法 2
ドメインをまたぐ場合は、POST リクエストのデータ本体に JWT を含めることができます。
方法 3
GET /calendar/v1/events
Host: api.example.com
Authorization: Bearer <token>复制代码</token> プロジェクトで JWT を使用する
トークンと JWT
の違いは同じです:
どちらもリソースにアクセスするためのトークンです
両方ともユーザー情報を記録できます#両方ともサーバーをステートレスにします #両方とも検証が成功した後にのみサーバー上の保護されたリソースにアクセスできます
## #違い:######
トークン: サーバーは、クライアントから送信されたトークンを検証するときに、データベースにクエリを実行してユーザー情報を取得し、トークンが有効かどうかを検証する必要もあります。
JWT: トークンとペイロードは暗号化され、クライアントに保存されます。サーバーは検証にキー復号化を使用するだけで済みます (検証は JWT 自体によっても実装されます)。クエリを実行したり、クエリを削減したりする必要はありませんJWT にはユーザー情報と暗号化されたデータが含まれるためです。
一般的なフロントエンドおよびバックエンドの認証方法
Session-Cookie
トークン検証 (JWT、SSO を含む)
OAuth2.0 (オープン認証)
共通暗号化アルゴリズム
ハッシュ アルゴリズム、ハッシュ関数、ハッシュ関数とも呼ばれるハッシュ アルゴリズムは、あらゆる種類のデータからデータを抽出する方法です。小さなデジタル「指紋」。ハッシュ アルゴリズムは、データを再シャッフルして新しいハッシュ値を作成します。
ハッシュ アルゴリズムは主にデータの信頼性 (整合性) を保証するために使用されます。つまり、送信者は元のメッセージとハッシュ値を一緒に送信し、受信者は同じハッシュ関数を使用して元のデータが正しいかどうかを確認します。本物です。
ハッシュ アルゴリズムには通常、次のような特徴があります。
高速: 元のデータからハッシュ値をすぐに計算できる
逆の難易度: 基本的にハッシュ値を渡すのが難しい元データを推定することが可能
入力感度: 元データが少しでも変化する限り、取得されるハッシュ値は大きく異なります
競合回避: 異なる元データを見つけることが困難同じハッシュ値を取得するには、宇宙内の原子の数はおよそ 10 の 60 乗と 80 乗の間であるため、2 の 256 乗にはすべての可能性を収容するのに十分なスペースがあります。アルゴリズムが良好であれば、衝突の確率は非常に低い: 2 の 128 乗は 340282366920938463463374607431768211456 で、10 の 39 乗レベルです。
2 の 160 乗は 1.4615016373309029182036848327163e 48 、これは 48 のうち 10 です。 level
2 256 乗は 1.1579208923731619542357098500869 × 10 の 77 乗、つまり 10 の 77 乗です。
#上記は、データが悪意のある改ざんであることを保証するものではありません。元のデータとハッシュ値の両方が悪意のある改ざんされる可能性があります。改ざんされないようにするために、RSA 公開キーと秘密キー スキームを組み合わせて使用できます。ハッシュ値。 ハッシュ アルゴリズムは、主にコンピュータ送信時のエラーを防ぐために使用されます。初期のコンピュータでは、データの最初の 7 ビットと 8 ビット目のパリティ チェック コードを使用してデータを保護していました (無駄効率は 12.5% と低い)。データやファイルをハッシュアルゴリズムで128ビットまたは256ビットのハッシュ値を生成し、検証に問題があった場合は再送が必要となります。
FAQ Cookie を使用する際に考慮すべき問題
Cookie はクライアントに保存されるため、クライアントによって簡単に改ざんされます。性別ユーザー パスワードやアカウント残高などの機密データを保存しない セキュリティをある程度向上させるために httpOnly を使用します Cookie のサイズと保存できるデータ量は 4kb を超えることはできません データ送信を減らすために正しいドメインとパスを設定してください
Cookie はドメインを越えることはできません ブラウザは 1 つの Web サイトに対して最大 20 個の Cookie を保存できます。 Cookie、ブラウザでは通常 300 個の Cookie しか保存できません。
モバイル端末は Cookie をあまりサポートしていないため、セッションを確立する必要があります。 Cookie に基づいて実装されるため、モバイル端末は通常トークンを使用します
セッション使用時に考慮すべき問題 ## セッションをサーバーに保存します。ユーザーが同時にオンラインになっている場合、これらのセッションはより多くのメモリを占有するため、サービスで使用する必要があります。クライアントは期限切れのセッションを定期的にクリーンアップします。
Web サイトが クラスター デプロイメント を採用すると、複数の Web サーバー間でセッションを共有する方法が問題になります。セッションは単一のサーバーによって作成されますが、ユーザー要求を処理するサーバーは必ずしもセッションを作成したサーバーではないため、サーバーは以前にセッションに入力されたログイン資格情報などの情報を取得できません。 複数のアプリケーションがセッションを共有したい場合、上記の問題に加えて、クロスドメインの問題も発生します。これは、異なるアプリケーションが異なるホストをデプロイする可能性があり、各アプリケーションがクロスドメイン Cookie を処理する必要があるためです。
sessionId は Cookie に保存されます。ブラウザが Cookie を禁止している場合、または Cookie をサポートしていない場合はどうなりますか? 通常、sessionId の後には URL を書き換えるための url パラメータが続くため、必ずしもセッションを Cookie で実装する必要はありません。
モバイル端末は Cookie をあまりサポートしていません、セッションは cookie に基づく必要があります。実装のため、トークンはモバイル端末でよく使用されます トークンを使用する際に考慮すべき問題
データベースを使用してトークンを保存すると、クエリ時間が長くなりすぎると考えられる場合は、トークンをメモリに保存することを選択できます。たとえば、redis はトークン クエリのニーズに非常に適しています。
トークンはアプリケーションによって完全に管理されるため、同一生成元ポリシーを回避できます
トークンは CSRF 攻撃を回避できます (Cookie が必要ないため)
モバイル端末は Cookie をあまりサポートしておらず、セッションは Cookie に基づいて実装する必要があるため、モバイル端末は通常トークンを使用します
#JWT を使用する場合はこれを考慮する必要があります問題
JWT は Cookie に依存しないため、クロスドメインのリソース共有の問題 (CORS) を心配することなく、任意のドメイン名を使用して API サービスを提供できます。 )
JWT デフォルトは暗号化されていませんが、暗号化することもできます。元のトークンを生成した後、キーを使用して再度暗号化できます。
JWT 秘密データは、暗号化せずに JWT に書き込むことはできません。
JWT は認証だけでなく、情報交換にも使用できます。 JWT を効果的に使用すると、サーバーがデータベースにクエリを実行する回数を減らすことができます。
JWT の最大の利点は、サーバーにセッションを保存する必要がなくなるため、サーバー認証および認証ビジネスを容易に拡張できることです。しかし、これは JWT の最大の欠点でもあります。サーバーはセッション状態を保存する必要がないため、使用中にトークンを破棄したり、トークンの権限を変更したりすることができません。つまり、JWT が発行されると、サーバーが追加のロジックをデプロイしない限り、有効期限が切れるまで常に有効になります。
JWT 自体には認証情報が含まれており、漏洩すると誰でもトークンのすべての権限を取得できます。盗難を減らすために、JWT の有効期間は比較的短く設定する必要があります。より重要な権限については、ユーザーが使用するときに再度認証する必要があります。
JWTはワンタイムコマンド認証に適しています。有効期限が非常に短いJWTが発行されます。リスクがあったとしてもリスクは非常に小さいです。操作ごとに新しいJWTが生成されるため、 JWT を保存する必要はなく、まさにシームレスな状態です。
盗難を減らすために、JWT は HTTP プロトコルを使用してプレーン コードで送信するのではなく、HTTPS プロトコルを使用して送信する必要があります。
暗号化アルゴリズムを使用するときに考慮すべき問題
をクリア テキストで保存しないでください パスワード
常に ha を使用しますパスワードを処理するためのハッシュ アルゴリズム。パスワードの保存には Base64 やその他のエンコード方法を決して使用しないでください。これは、パスワードをクリア テキストで保存するのと同じです。エンコード の代わりにハッシュを使用してください。エンコードと暗号化はどちらも双方向のプロセスですが、パスワードは機密であり、その所有者のみが知る必要があります。このプロセスは一方向である必要があります。ハッシュをデコードするなどということは決してありませんが、エンコードがある場合にはデコードがあり、暗号化がある場合には復号化が行われます。
MD5 や SHA1 などの弱いハッシュ アルゴリズムや侵害されたハッシュ アルゴリズムは決して使用せず、強力なパスワード ハッシュ アルゴリズムのみを使用してください。
パスワードの所有者であっても、パスワードをクリア テキストで表示したり送信したりしないでください。 「パスワードを忘れた場合」機能が必要な場合は、新しい ワンタイム (これは非常に重要です) パスワードをランダムに生成し、このパスワードをユーザーに送信できます。
分散アーキテクチャ下でのセッション共有スキーム
1. セッションのレプリケーション
いずれかのサーバー上のセッションが変更されると (追加、削除、または変更)、ノード このセッションのすべてのコンテンツはシリアル化され、他のサーバーがセッションを必要とするかどうかに関係なく、他のすべてのノードにブロードキャストされ、セッションの同期が保証されます
利点: フォールトトレラント、さまざまなサーバー間のセッションはリアルタイムで応答できます。 欠点: ネットワーク負荷に一定の負荷がかかり、セッション数が多い場合、ネットワークの輻輳が発生し、サーバーのパフォーマンスが低下する可能性があります。
2. スティッキーセッション/IP バインディング戦略
Ngnix の ip_hash メカニズムを使用して、特定の IP に対するすべてのリクエストを同じサーバーに送信します。サーバー。 ユーザーが初めてリクエストを行うと、ロード バランサーはユーザーのリクエストをサーバー A に転送します。ロード バランサーがスティッキー セッションを設定すると、ユーザーの後続のすべてのリクエストはサーバー A に転送されます。これは次と同等です。ユーザーのリクエストをサーバー A に転送します。ユーザーとサーバー A はくっつきます。これがスティッキー セッション メカニズムです。
利点: シンプルで、セッションで処理を行う必要はありません。 欠点: フォールト トレランスの欠如: 現在アクセスしているサーバーに障害が発生し、ユーザーが 2 番目のサーバーに転送された場合、ユーザーのセッション情報は無効になります。 該当するシナリオ: 障害が顧客に与える影響はわずかです。サーバー障害は確率が低いイベントです。
。 実装方法: Nginx を例に挙げると、上流モジュールで ip_hash 属性を設定することでスティッキー セッションを実現できます。
3. セッション共有 (一般的に使用されます)
Memcached や Redis などの分散キャッシュ ソリューションを使用してセッションをキャッシュしますが、Memcached または Redis はクラスターである必要があります。 Redis のストレージでセッションを使用すると、アーキテクチャが複雑になり、Redis へのアクセスが 1 つ必要になりますが、このソリューションによってもたらされるメリットも大きくなります。
セッション共有を実現します。
水平方向に使用できます。 (Redis サーバーの追加);
サーバーが再起動されてもセッションは失われません (ただし、Redis のセッション更新/無効化メカニズムにも注意してください);
サーバーセッション間で共有できるだけでなく、プラットフォーム (Web ページやアプリなど) 全体で共有することもできます。
セッションの永続性を確保するため、セッションをデータベースに保存します
利点: サーバーに問題がある場合、セッションは #欠点: Web サイトへのアクセス数が非常に多い場合、セッションをデータベースに保存するとデータベースに大きな負荷がかかり、データベースを維持するために追加のオーバーヘッドが必要になります。 。
ブラウザを閉じる限り、セッションは本当に消えますか? #########間違っている。セッションの場合、プログラムがサーバーにセッションの削除を通知しない限り、サーバーはセッションを保持します。通常、プログラムはユーザーがログオフするときにセッションを削除する指示を送信します。 ただし、ブラウザは閉じる前にサーバーに、閉じようとしていることを積極的に通知することはないため、サーバーはブラウザが閉じられたことを知る機会がありません。この錯覚の理由は、ほとんどのセッション メカニズムがセッション Cookie を使用しているためです。セッション ID は保存されますが、ブラウザを閉じるとセッション ID が消え、サーバーに再度接続すると元のセッションが見つかりません。サーバーによって設定された Cookie がハードディスクに保存されている場合、またはブラウザーによって送信された HTTP リクエスト ヘッダーを書き換えて元のセッション ID をサーバーに送信する何らかの方法が使用されている場合、ブラウザーの起動時に元のセッションを開くことができます。再び開きました。 まさにそのとおりです ブラウザを閉じてもセッションは削除されないため、サーバーはセッションの有効期限を設定する必要があります。クライアントが最後にセッションを使用してからの時間がこの有効期限を超えると、サーバーはクライアントを考慮してください。 セッションは、ストレージ領域を節約するためにアクティビティが停止した後にのみ削除されます。 プロジェクト アドレス
プロジェクトでの JWT の使用
追記 この記事は、以下にのみ基づいています。私自身、バックエンドやアルゴリズムの知識にあまり詳しくないため、理論的な知識について話したと理解しています。誤解がある場合は、お知らせください。ありがとうございます。 もしこの記事が役に立ちました、いいねをお願いします~~