フロントエンドとバックエンドの認証方法に関する簡単な説明

一般的な認証メカニズム

HTTP はステートレス プロトコルです (トランザクション処理用のメモリがなく、サーバーはクライアントとサーバーのセッションが完了するたびにセッション情報を保存しません): 各リクエストは完全に独立しており、サーバーは現在の ID を確認できません。訪問者の情報では、前回のリクエストの送信者と今回の送信者が同一人物であるかどうかはわかりません。したがって、セッションを追跡する (誰が私を訪問しているのかを知るため) ために、サーバーとブラウザーは積極的に状態を維持する必要があります。この状態は、前後の 2 つのリクエストが同じブラウザーからのものであるかどうかをサーバーに通知するために使用されます。結果として、さまざまな種類の認証方法が生まれます。

  • HTTP基本認証
  • セッションクッキー
  • トークン
  • OAuth

この記事の特典として、無料の Linux C/C++ 開発学習教材パッケージ、技術ビデオ/コード、主要メーカーからの 1,000 件のインタビュー質問 (C++ の基礎、ネットワーク プログラミング、データベース、ミドルウェア、バックエンド開発/オーディオおよびビデオ開発/Qt 開発/ゲーム開発/Linuxn カーネルお​​よびその他の高度な学習教材と最適な学習ロードマップ) ↓↓↓↓↓↓以下を参照してください↓↓記事の下部をクリックして無料で入手してください↓↓

さらに、認証と認証の区別に注意する必要があります。1 つは認証で、もう 1 つは承認。認証は自分であることを確認すること、承認は自分に何かをする権限があるかどうかを確認することです。誰もが認証と認可の関係をより深く理解できるように、3 つの状況をそれぞれ 3 つの例で説明します。

  • 認証のみを行い、認可は行いませんアプリケーションにログインするだけで、他の操作は実行しません。この時点では、認可は必要なく、認証のみが実行されます。
  • 認証と認可の両方サードパーティ アプリケーションを使用してログインする場合、認証のためにサードパーティ アプリケーションのアカウントとパスワードを入力するだけでなく、認可も行います。本アプリは、第三者のログインアプリに登録された個人情報データ等を読み込むためのものです。
  • 認証なし、許可のみミニ プログラムをクリックすると、個人情報を取得する必要があります。この時点では、データをミニ プログラムに許可せずにのみ許可することと同じです。結局のところ、アプリケーション内で小さなプログラムを内部で使用する場合、認証のためにログインする必要はほとんどありません。

各認証メカニズムのプロセスと原則

  認証と認可が関わると考えなければならないのはステータス管理です。いわゆるステータス管理とは、一定期間ログインした後、アクセスするたびに再度ログインする必要がないようにすることを意味します。したがって、開発者は、ユーザーのログイン状態を維持し、有効期限を設定する方法を検討する必要があります。このプロセスを完了するには、フロントエンドとバックエンドが連携して動作する必要があります。

  • いくつかの一般的な認証および認可方法のプロセスと原則について簡単に説明しましょう。私はただナンセンスなことを話しているだけです。アドバイスを歓迎します。

HTTP基本認証

  この認証方法は、HTTP プロトコルに準拠するブラウザによって実装される基本的な認証方法です。HTTP プロトコルは、HTTP サーバーがクライアント上でユーザーの識別を実行できるようにする基本的な認証方法を定義します。

基本的なプロセス

  • リクエストの送信: クライアントはサーバーにデータを要求します。要求されたコンテンツは Web ページまたは Ajax 非同期リクエストです。このとき、クライアントが検証されていないものと仮定します (サーバーは検証して 401 を返すかどうかを決定します)。クライアントは次のリクエストをサーバーに送信します。
Get /index.html HTTP/1.0 
Host: www.google.com
  • サーバーは 401 を返します: サーバーは検証リクエスト コード 401 をクライアントに送信します。 WWW-Authenticate: Basic realm="google.com" この文がキーです。クライアントが存在しない場合、ユーザー名とパスワードの入力インターフェイスはポップアップしない サーバーから返されるデータ おおよそ以下の通りです。
HTTP/1.0 401 Unauthorised 
Server: SokEvo/1.0 
WWW-Authenticate: Basic realm="google.com"
Content-Type: text/html 
Content-Length: xxx
  • クライアント ポップアップ ウィンドウ: http1.0 または 1.1 仕様に準拠するクライアントが 401 戻り値を受け取ると、ログイン ウィンドウが自動的にポップアップし、ユーザーはユーザー名とパスワードの入力を求められます。この時点では、リクエストは保留状態にあり、ユーザーがユーザー名とパスワードを入力すると、クライアントは Authorization ヘッダーを付けてリクエストを再送信します。
  • ユーザーがユーザー名とパスワードを入力します: パスワードを入力した後、送信をクリックすると、ユーザー名とパスワードが Base64 暗号化で暗号化され、前回のリクエスト情報に暗号文が組み込まれ、クライアントから送信される最初のリクエスト情報は次の内容になります。
Get /index.html HTTP/1.0 
Host: www.google.com
Authorization: Basic xxxxxxx(base64 密文)
// 加密过程是浏览器默认的行为,不需要我们人为加密,我们只需要输入用户名密码即可。
  • サーバー側の復号化: 上記のリクエスト情報を受信したサーバーは、Authorization フィールド以降のユーザー情報を取り出して復号化し、復号化されたユーザー名とパスワードをユーザー データベースと比較して検証し、ユーザー名とパスワードが正しい場合は、サーバーは、リクエストに基づいて、リクエストされたリソースをクライアントに送信します。

利点: シンプルで便利、優れた互換性。

短所: TLS/SSL を使用しない場合、情報が漏洩しやすく安全ではありません。ログアウトできず、ブラウザまたはタブを閉じることしかできません。

セッションクッキー

  この認証方法は、サーバー側のセッションとブラウザ (クライアント) の Cookie を使用して実装されるフロントエンドおよびバックエンドの通信認証モードです。 HTTP プロトコルはステートレス プロトコルであり、サーバーはどのブラウザがアクセスしているかを認識しないため、サーバーが異なるブラウザを区別できるようにするための識別子が必要です。 Cookieはサーバーとクライアント間の状態を管理する識別子です。 Cookie の原理は、ブラウザが初めてサーバーにリクエストを送信すると、サーバーは応答ヘッダーに Set-Cookie フィールドを設定し、ブラウザが応答を受信すると、Cookie を設定して保存します。次回ブラウザがサーバーにリクエストを送信すると、リクエスト ヘッダーに Cookie フィールドが自動的に追加され、サーバーは異なるブラウザを区別するために Cookie を受け取ります。もちろん、初回訪問時には、この Cookie と特定のユーザーとの対応関係がサーバー側に存在する必要があり、その場合にはセッションが必要になります。また、Cookie の有効期限を忘れずに設定してください。有効期限を設定せずにブラウザを閉じるとクッキーは消えますが、有効期限を設定するとローカル ディスクに保存されます。サーバーはセッションの構成も忘れないため、特に分散サーバーでは、認証メカニズムにおける Cookie 共有やセッション共有などの問題を考慮する必要があります。セッションとはセッションのことで、ブラウザが初めてサーバーにアクセスしたときに、サーバーはセッションを作成し、セッション内にブラウザを識別する情報を保存します。 Cookie との違いは、セッションはサーバー側でキャッシュされるのに対し、Cookie はクライアント側でキャッシュされることです。どちらも HTTP プロトコルのステートレスな欠陥を補うためにサーバー側で生成されます。リクエストがサーバーに到達すると、まずリクエスト内のユーザー ID がセッション内に存在するかどうかがチェックされ、存在する場合は認証が成功したことを意味し、存在しない場合は認証が失敗したことを意味します。

基本的なプロセス

  • サーバーがクライアントの最初のアクセスを受け入れると、サーバー側でセッションを作成し、そのセッションを保存します (セッションはメモリまたは Redis に保存できます。後者をお勧めします)。その後、このセッションの一意の識別子を生成します。 . 文字列 sessionId(sid)。
  • クライアントが SID を変更できないようにするには、秘密キー (カスタム) を使用して SID に署名します。 (必須ではない手順) SID を生成した後、その SID をユーザー情報にマッピングしてサーバーに保存し、最後にこの一意の識別文字列を応答ヘッダーに埋め込みます (set-cookie)。
  • ブラウザーはリクエスト応答を受信すると、レスポンス ヘッダーを解析し、その sid をローカル Cookie に保存し、次の http リクエストのリクエスト ヘッダーのドメイン名の下に Cookie 情報を含めます。
  • サーバーが後でクライアント リクエストを受け入れると、リクエスト ヘッダー Cookie 内の sid を解析し、この sid を使用してサーバーに保存されているクライアントのセッションを検索し、リクエストが正当であるかどうかを判断します。
  • 後続のリクエストでは、サーバーは常に sid に基づいて認証を行い、認証に合格した場合は処理を続行します。ユーザーがログアウトすると、サーバーとクライアントの両方がセッションを破棄します。

利点: シンプルで便利、ブラウザが自動的にそれを取得します; 毎回比較するためにデータベースからデータを取得する必要はありません (SID がサーバーに保存されていない場合); ユーザーのログアウトとログインを簡単に管理できます (削除/追加)セッション)。

デメリット:モバイル端末やPC端末などのブラウザがないと利用できない; セッションがサーバー側に保存されるためサーバーのオーバーヘッドが増加する; サーバー側にsidが存在するため、誰かがsidを取得すると、クロスサイト リクエスト フォージェリ (CSRF) 攻撃の影響を受けやすいため、HttpOnly を設定できます (スクリプトはローカルに保存された SID を読み取ることができません。これにより、XSS インジェクションによる Cookie 内の SID の取得が防止され、攻撃が偽造されます)。セキュリティを向上させるために、Secure は true (HTTPS を使用) に設定されます。分散サーバーでは、セッションなどの構成を共有する必要があるため、負荷分散やクラスターの水平拡張の機能が制限されます。

  • セッションは Cookie メカニズムにも依存しているため、Cookie よりも安全であることに加えて、Cookie 認証にはセッションの他のほぼすべての欠点があります。ただし少し違いがあり、セッション Cookie の認証方法は Cookie 認証のみを使用する場合よりも少し異なります。セッションは Cookie よりも安全であり、セッションはサーバー側に保存され、Cookie はクライアント側に保存されます。 Cookie は文字列データの保存のみをサポートします。他のタイプのデータを設定したい場合は、それを文字列に変換する必要があります。セッションは任意のデータ タイプを保存できます。 Cookie は、私たちがよく使用するデフォルトのログイン機能など、長期間保持するように設定できます。セッションの有効期限は通常短く、クライアントが閉じられる (デフォルト) かセッションがタイムアウトすると期限切れになります。 1 つの Cookie に保存されるデータは 4K を超えることはできず、セッションには Cookie よりもはるかに多くのデータを保存できますが、アクセス数が多すぎると、サーバー リソースを過剰に占有することになります。
  • Cookie認証の基本的な流れ

トークン

トークンの認可

  トークンはトークンとも呼ばれます。本質的には意味のない文字列です。通常はリクエスト ヘッダーに配置されます。リクエスト ヘッダーのキーは通常 Authorization です。もちろん、サーバーと合意することで他の値にカスタマイズすることもできます。サーバーが要求ヘッダー内のトークンを取得できる限り。トークン認証の登場の最大の特徴は、ログイン認証がCookieの仕組みに依存しなくなったことであり、リクエストヘッダにトークンを置くことでCookieの仕組みによるデメリットが自然に解消されます。

  • クライアントは、ユーザー名とパスワードを使用してログインを要求します。
  • サーバーはユーザー名とパスワードを確認するリクエストを受け取ります。
  • 検証が成功すると、サーバーはカスタム ルールに基づいてトークンを発行し、そのトークンをクライアントに送信します。
  • トークンを受信した後、クライアントはそれを Cookie や LocalStorage などに保存できます。
  • クライアントがサーバーにリソースを要求するたびに、サーバーによって発行されたトークンを取得し、それをリクエスト ヘッダーの Authorization に入れる必要があります。
  • サーバーはリクエストを受信し、クライアントのリクエストに含まれるトークンを検証し、検証が成功した場合はリクエストされたデータをクライアントに返します(発行されたトークンをデータベースから照会し、ユーザーデータを照会します)。 401 エラー コードを返します。認証に失敗しました。

利点: トークン認証は Cookie に限定されず、同一生成元ポリシーの影響を受けません。リクエスト ヘッダーの特定のフィールドに指定でき、アプリケーションで使用できます。Cookie を使用しないと、攻撃者はトークンがどこにあるかを推測できません。ユーザーのトークンはローカルに保存され、リクエストの送信時にサーバーが読み取るためにリクエスト ヘッダーの特定のフィールドにのみ配置されます (スクリプトでは読み取れないリファラーの取得と同様です)。これにより、CSRF を回避できます。ある程度の攻撃が可能。

欠点: 暗号化と復号化の消費により、トークン認証は Session-Cookie よりもパフォーマンスを消費します。トークンは sessionId より大きく、より多くの帯域幅を占有します。トークンはデータベース内のユーザー情報をクエリする必要があるため、データベースの負荷が増加します。

JWT (JSON ウェブトークン)

  各リクエストにはデータベース内のユーザー情報を照会するためのトークンが必要なため、データベースへの負担が大きすぎます。トークンにユーザー情報が含まれている場合、リクエストのたびにデータベースにアクセスする必要はなく、トークンからユーザー情報やユーザーのログイン状態を直接解析して検証することができます。これが JWT です。ブラウザに返されるトークンは、ユーザー情報を含む暗号化された文字列です。 JWT の正式名は Json Web Token です。実際、これは特別なトークンであり、ユーザー情報を運ぶトークンとして理解されています。したがって、JWT 認証とトークン認証は本質的に同じです。ただし、トークン認証のユーザー情報はデータベースから確認されます。 JWT 認証のユーザー情報はトークンから直接解析されます。

JWTの構成

ヘッダ

  • Header部分は図に示すようにJWTのメタデータを記述したJSONオブジェクトです。上記のコードでは、alg 属性は署名アルゴリズム (アルゴリズム) を表しており、デフォルトは HMAC SHA256 (HS256 と書きます) です。 typ 属性は、このトークンのタイプを示します。JWT トークンは一律に JWT として記述されます。最後に、Base64URL アルゴリズムを使用して、上記の JSON オブジェクトを文字列に変換します (詳細は以下を参照)。

ペイロード

  • ペイロード部分も JSON オブジェクトであり、転送する必要がある実際のデータを保存するために使用されます。 JWT では、選択用に 7 つの公式フィールドが指定されています。
iss (issuer):签发人
exp (expiration time):过期时间
sub (subject):主题
aud (audience):受众
nbf (Not Before):生效时间
iat (Issued At):签发时间
jti (JWT ID):编号
除了官方字段,你还可以在这个部分定义私有字段,比如用户名、用户昵称、权限、部门等等。
注意,JWT 默认是不加密的,任何人都可以读到,所以不要把秘密信息放在这个部分。
这个 JSON 对象也要使用 Base64URL 算法转成字符串。

サイン

  • 署名部分は、データの改ざんを防ぐための最初の 2 つの部分の署名です。まず、シークレットを指定する必要があります。このキー (カスタム) はサーバーのみに知られており、ユーザーに漏洩することはできません。次に、ヘッダーで指定された署名アルゴリズム (デフォルトは HMAC SHA256) を使用して、次の式に従って署名を生成します。 HMACSHA256(base64UrlEncode(header) + "." +base64UrlEncode(payload), Secret) 署名を計算したら、Header、Payload、Signature の 3 つの部分を文字列にまとめ、各部分を で区切ってユーザーに返します。

Base64URL アルゴリズム

  先ほども述べたように、HeaderとPayloadをシリアル化するアルゴリズムはBase64URLです。このアルゴリズムは基本的に Base64 アルゴリズムと似ていますが、いくつかの小さな違いがあります。 JWT はトークンであり、URL に配置される場合があります(http://api.example.com/?token=xxx など)。 Base64 には +、/、= の 3 つの文字があり、URL 内で特別な意味を持つため、これらを置き換える必要があります。= は省略され、+ は - に置き換えられ、/ は _ に置き換えられます。これは Base64URL アルゴリズムです。

基本的なプロセス

上記の内容を理解した上で、簡単にプロセスを説明しましょう。

  • 基本的な処理はトークンと同様ですが、発行されるトークンの内容が異なります。
  • JWT はユーザー情報を保存すると前述したため、主に行う必要があることは次のとおりです。クライアントはユーザー名とパスワードを使用してログインを要求し、サーバーはその要求を受信して​​ユーザー名とパスワードを検証します。検証が成功すると、サーバーはカスタム キーとユーザー情報に基づいてトークンを発行し、そのトークンをクライアントに送信します。トークンを受信した後、クライアントはそれを Cookie や LocalStorage などに保存できます。クライアントがサーバーからリソースをリクエストするたびに、サーバーによって発行されたトークンを取得し、それをリクエスト ヘッダーの Authorization に入れる必要があります。もちろん、それを Cookie に入れることもできますが、これはドメインをまたぐことはできません。認証: Bearer <token> 受信後、サーバーはヘッダー内の暗号化アルゴリズムとカスタム キーに基づいてペイロード コンテンツを暗号化します。生成された結果が署名と一致する場合は認証に合格し、そうでない場合は認証が失敗することを意味します。

補充する

  • JWT はデフォルトでは暗号化されませんが、暗号化することもできます。元のトークンを生成した後、キーを使用して再度暗号化できます (フロントエンドがトークン内の関連情報を使用する必要がある場合は、エンコード ルールを指定してください)。
  • 機密データは、暗号化せずに JWT に書き込むことはできません。
  • JWTは認証だけでなく情報のやり取りにも利用できます。 JWT を効果的に使用すると、サーバーがデータベースにクエリを実行する回数を減らすことができます。
  • JWT の最大の欠点は、サーバーがセッション状態を保存しないため、使用中にトークンを取り消したり、トークンの権限を変更したりできないことです。つまり、JWT が発行されると、サーバーが追加のロジックをデプロイしない限り、有効期限が切れるまで常に有効ですが、キーと解析暗号化ロジックがすべてコード内にあるため、分散サーバー管理が容易になるという利点もあります。 。
  • JWT 自体には認証情報が含まれており、一度漏洩すると誰でもトークンのすべての権限を取得できます。盗難を減らすために、JWT の有効期間は比較的短く設定する必要があります。より重要な権限については、ユーザーが使用するときに再度認証する必要があります。
  • 盗難を減らすために、JWT は HTTP プロトコルを使用してプレーン コードで送信するのではなく、HTTPS プロトコルを使用して送信する必要があります。
  • JWTの有効期間は比較的短く設定する必要があるため、ログイン状態情報の更新が問題となります。たとえば、トークンの有効期間が 1 時間に設定されている場合、ユーザーが 1 時間後にまだアプリケーションを使用している場合、当然、この時点でユーザーが再度ログインすることは期待できません。現在利用可能な解決策は、ユーザーがリクエストを行うたびに新しいトークンを返し、フロントエンドがこの新しいトークンを使用して古いトークンを置き換え、トークンの有効期間がリクエストごとに更新されるようにすることです。ただし、これには頻繁にトークンを生成する必要があります。もう 1 つの解決策は、ユーザーがリクエストを行うたびにトークンの有効期限が切れるまでにかかる時間を決定し、トークンの有効期限が近づくと新しいトークンを返すことです。フロントエンドが毎回リクエストヘッダーを自分で操作したくない場合は、set-cookie と http-only と HTTPS を設定するだけで、Cookie にリクエストヘッダーを配置できます。
  • ユーザーがアクティブにログアウトする場合、JWT はユーザーのアクティブ ログアウトをサポートしませんが、クライアントは他の場所でトークンを使用することで通常どおりアクセスできます。ログアウトをサポートするには、サーバーの Redis ブラックリストにトークンを追加するか、ログアウト時にデータベース ストレージを設定します。

OAuth

  OAuth プロトコルは、ユーザー リソース認証のための安全でオープンかつシンプルな標準を提供します。以前の認証方法との違いは、OAuth 認証では第三者がユーザーのアカウント情報 (ユーザー名やパスワードなど) にアクセスすることを許可しないことです。つまり、第三者はユーザーのユーザー名やパスワードを使用せずにユーザーのリソースの取得を申請できます。パスワードと認証のため、OAuth は安全です。同時に、あらゆるサードパーティが OAuth 認証サービスを使用でき、あらゆるサービス プロバイダーが独自の OAuth 認証サービスを実装できるため、OAuth はオープンです。 OAuth 認証サービスを提供する一般的なベンダーには、Alipay、QQ、WeChat、Weibo、Github などが含まれます。 OAuth プロトコルには 1.0 と 2.0 の 2 つのバージョンがあります。 1.0 (重大なセキュリティ脆弱性のため無効になっています) と比較して、バージョン 2.0 の認証検証プロセス全体はよりシンプルかつ安全であり、現在最も重要なユーザー認証および認可方法です。

  • JWT との違いOAuth2.0 は、QQ を使用してサードパーティ アカウントにログインする場合など、サードパーティ アカウントを使用してログインするときに使用される認可フレームワーク (認証プロセスの概念) です。アプリ 。 JWT は、フロントエンドとバックエンドを分離し、バックエンド API を単純に保護する必要がある場合に使用される認証プロトコル (認証方法) です。どの方法を使用する場合でも、データのセキュリティを確保するために必ず HTTPS を使用してください

基本的なプロセス

  • 認証のリクエスト (サードパーティ アプリケーションが正規かどうかの証明): クライアント (サードパーティ アプリケーション) は、OAuth サービス プロバイダーに未承認の RequestToken を要求します。つまり、RequestToken URL に対してリクエストが行われます。 OAuth サービス プロバイダーはユーザーのリクエストに同意し、ユーザーに承認されていない oauth_token と対応する を発行します。ユーザー oauth_token_secret を返し、ユーザーに返します。
  • ユーザーの同意 (ユーザーが同意するかどうかの確認): ユーザーは、OAuth サービスプロバイダーに対して、ユーザーが承認した RequestToken を要求します。つまり、UserAuthorization URL へのリクエストを開始し、前のステップでサービス プロバイダーによって発行された未承認の oauth_token と oauth_token_secret を送信します。 OAuth サービス プロバイダーは、ユーザーに Web ページ経由でログインすることを要求し、ユーザーが認証を完了するようにガイドします。
  • AccessToken と引き換えに (AccessToken と RefreshToken (オプション) をサードパーティ アプリケーションに提供): RequestToken が承認されると、ユーザーは AccessToken URL へのリクエストを開始し、 前のステップAccessTokenRefreshToken と引き換えに承認されたRequestToken 。 OAuth サービス プロバイダーはユーザーのリクエストに同意し、AccessToken と対応するキーを発行してユーザーに返します。
  • リソースと引き換えに AccessToken を使用する (サードパーティ アプリケーションは、AccessToken を通じてユーザーによって承認された関連リソースを取得します): ユーザーは、前の手順で返された AccessToken を後で使用して、ユーザーによって承認されたリソースにアクセスできます。 AccessToken を使用してリソースを交換できませんでした。RefreshToken を使用して、新しい AccessToken

OAuth2.0では4つの認可モードが用意されており、開発者は自社のビジネス状況に合わせて自由に選択することができます。

  1. 認可コードグラント
  2. インプリシットグラントモード(簡易モード)(Implicit Grant)
  3. パスワード認証モード (リソース所有者パスワード認証情報の付与)
  4. クライアント資格情報の付与
  • OAuth2.0 と 4 つのモードを理解するには、Ruan Yifeng 教師の紹介を参照してください。

シングルサインオン拡張機能

JWT シングル サインオン プロセス

セッションシングルサインオンプロセス

この記事の特典として、無料の Linux C/C++ 開発学習教材パッケージ、技術ビデオ/コード、主要メーカーからの 1,000 件のインタビュー質問 (C++ の基礎、ネットワーク プログラミング、データベース、ミドルウェア、バックエンド開発/オーディオおよびビデオ開発/Qt 開発/ゲーム開発/Linuxn カーネルお​​よびその他の高度な学習教材と最適な学習ロードマップ) ↓↓↓↓↓↓以下を参照してください↓↓記事の下部をクリックして無料で入手してください↓↓

おすすめ

転載: blog.csdn.net/m0_60259116/article/details/134949707