web-dev-qa-db-ja.com

アクセストークンと更新トークンを使用したトークンベースの認証

REST APIに短期間のアクセストークンと長期の更新トークンを使用して、トークンベースの認証システムを実装しています。これは、関連するAPIエンドポイントの概要です(HTTPSはすべてのエンドポイントに適用):

エンドポイント:

POST /register/
POST /login/
POST /logout/
POST /password/change/

実装:

POST /register/

  • リクエスト:クライアントはユーザー名、メール、パスワードをJSONで送信します。
  • サーバーアクション:
    1. 入力を検証し、データベースにユーザーを作成します(ユーザーID、ユーザー名、電子メール、パスワードハッシュを格納します)。
    2. JWT形式で短期間有効なアクセストークンを作成します(ユーザーID、発行日、有効期限が含まれます)。
    3. 長期間有効な更新トークンをUUID文字列として作成し、データベースに保存します(ユーザーIDと更新トークンを保存します)。
  • 応答:サーバーはJSONでアクセストークンと更新トークンを返します。

POST /login/

  • リクエスト:クライアントはJSONでユーザー名とパスワードを送信します。
  • サーバーアクション:
    1. 入力を検証し、データベースをチェックして資格情報が有効かどうかをチェックします。
    2. 資格情報が有効な場合、前述のように、有効期間が短いアクセストークンと有効期間が長いリフレッシュトークンを作成します。
  • 応答:/register/と同じで、アクセストークンと更新トークンをJSONで返します。

POST /logout/

  • リクエスト:クライアントは、Authorizationヘッダー内のrefreshトークンをBearerトークンとして送信します。
  • サーバーアクション:
    1. 更新トークンデータベースをチェックして、更新トークンを検証します。
    2. データベースから更新トークンを削除します。
      注:これによりアクセストークンは有効なままになりますが、有効期間が短いため(1時間程度なので、問題ないはずです)。
  • 応答:ログアウト要求がJSONで正常に処理されたかどうかを返します。

POST /password/change/

  • リクエスト:クライアントはaccessトークンをAuthorizationヘッダーでBearerトークンとして送信し、古いパスワードと新しいパスワードをHTTPS経由でJSONで送信します。
  • サーバーアクション:
    1. アクセストークンをデコードしてユーザーを取得し、ユーザーの古いパスワードをデータベースで確認します。
    2. データベース内のユーザーのパスワードハッシュを新しいパスワードのハッシュに設定します。
    3. リフレッシュトークンデータベース内のユーザーに関連付けられたすべてのリフレッシュトークンを削除して、基本的に既存のセッションをログアウトします(有効期間の短いアクセストークンを残します)。
  • 応答:パスワード変更リクエストがJSONで正常に処理されたかどうかを返します。

質問:

  1. このアプローチは安全ですか?具体的には:
    • HTTPS経由で行われる場合、JSONを介したユーザー名とパスワードの送信は安全ですか?無許可のドメインがこのエンドポイントに電話をかけることをどのように防ぐことができますか?さらに、プログラムによるログインを防ぐにはどうすればよいですか?
    • 更新トークンは、データベースに保存する前にハッシュ化する必要がありますか、それとも単なる偏執狂ですか?
  2. クライアントがWebブラウザーの場合、更新トークンをクライアントに安全に保存するにはどうすればよいですか?
    • 更新トークンを保存するための1つのアイデアは、ユーザーがログインすると、更新トークンをクライアントに送信するだけでなく、サーバーがHttpOnly Cookieにsecureを付けてトークンを保存することです。国旗。承認は引き続きAuthorizationヘッダーを介して行われますが、クライアントが最初にロードするときに、Cookieに有効な更新トークンが含まれているかどうかをチェックするエンドポイントにGETリクエストを送信できます。そのため、JSONでユーザーに返します。つまり、Cookieが実際に使用されるのは、Cookie内の更新トークンをクライアントに返すときだけです。このアプローチは安全ですか? Cookieから更新トークンを要求するときに副作用がないため、CSRFを防ぐことができると思いますが、攻撃者が更新トークンを傍受する別の方法があります(HTTPSを想定)?
8
Kootling

このアプローチは安全ですか?具体的には:

  • HTTPS経由で行われる場合、JSONを介したユーザー名とパスワードの送信は安全ですか?

はい。ヘッダー、要求パラメーター、および要求本文は、通信中に暗号化されます。

サーバー側では、リクエストの本文をログに記録しないでください:-)

  • 無許可のドメインがこのエンドポイントに電話をかけることをどのように防ぐことができますか?

できません。基本的に、APIがWWWに公開されると、あらゆる種類の悪意に自動的にさらされます。あなたができる最善のことは、準備をして脅威を認識することです。少なくともあなたに関係するものについて。 こちらをご覧ください

この問題への可能なアプローチは、 API Manager を実装(または縮小)することです。

AMの背後にあるすべてのエンドポイントが必ずしもパブリックであるとは限らないため、オンプレミスAPIマネージャーは攻撃対象を減らすことができます。

クラウド内の一部の製品で同じ結果を得ることができますが、それらは主流にとっては驚くほど高価です。

とにかく、API管理エンドポイントは攻撃にさらされたままになります。

  • さらに、プログラムによるログインを防ぐにはどうすればよいですか?

プログラムによるログインによってブルートフォースによる攻撃を意味する場合、threshold(1秒あたりの許可されるリクエストの最大数)とブラックリストで十分です。攻撃者の主張。詳細については、 こちら をご覧ください。

API Managerの多くは、すぐに使用できるAPIレート制限構成と Whitelists を提供します。

Google API Consoleに精通している場合は、API Managerが何を実行できるかを推測できます。

  • 更新トークンは、データベースに保存する前にハッシュ化する必要がありますか、それとも単なる偏執狂ですか?

更新トークンがプレーンなUUIDであるかどうかに関係なく、この種の実装の詳細を公開したくありません。だから私はそれをハッシュ化することをお勧めします。私にとって、セキュリティ層の実装の詳細は不透明であるほど良いです。

JWTのセキュリティについては、 こちら をご覧ください。

  • クライアントがWebブラウザーの場合、更新トークンをクライアントに安全に保存するにはどうすればよいですか?

JSON Web Token(JWT)-クライアント側のストレージ に興味があるかもしれません。

2
Laiv