(これは実際には独自の問題であり、NodeJSなどに固有ではないため、このスレッドから生成されます)
私は認証付きのREST APIサーバーを実装しています。ユーザーが/ loginエンドポイントを介してユーザー名/パスワードでログインできるように、JWTトークンの処理を正常に実装しました。このとき、サーバーシークレットからJWTトークンが生成され、クライアント。次に、トークンは、認証された各APIリクエストでクライアントからサーバーに渡され、サーバーシークレットを使用してトークンが検証されます。
ただし、本当に安全なシステムを作成するために、トークンを検証する方法と範囲を正確に確認するためのベストプラクティスを理解しようとしています。トークンの「検証」には、正確には何が必要ですか?サーバーシークレットを使用して署名を検証できれば十分ですか、それともサーバーに保存されている一部のデータに対してトークンやトークンペイロードをクロスチェックする必要がありますか?
トークンベースの認証システムは、ユーザーのパスワードを取得するよりもトークンを取得するのが同等または難しい場合に限り、各リクエストでユーザー名/パスワードを渡すのと同じくらい安全です。ただし、私が見た例では、トークンを生成するために必要な唯一の情報は、ユーザー名とサーバー側の秘密です。これは、悪意のあるユーザーが1分間サーバーシークレットの知識を得たと仮定すると、任意のユーザーに代わってトークンを生成できるため、パスワードがあった場合と同じように、特定のユーザーだけにアクセスできないことを意味します。取得しましたが、実際にはすべてのユーザーアカウントに対してですか。
これは私に質問をもたらします:
1)JWTトークンの検証は、トークン自体の署名の検証、サーバーシークレットの整合性のみに依存する、または個別の検証メカニズムを伴うものに限定する必要がありますか?
場合によっては、/ loginエンドポイントを介したログインが成功するとセッションが確立されるトークンとサーバーセッションの組み合わせの使用を見てきました。APIリクエストはトークンを検証し、トークンにあるデコードされたデータをセッションに保存されている一部のデータと比較します。ただし、セッションを使用することはCookieを使用することを意味し、ある意味でトークンベースのアプローチを使用する目的に反します。また、特定のクライアントに問題を引き起こす可能性があります。
サーバーがmemcacheなどで現在使用中のすべてのトークンを保持していると想像できます。これにより、サーバーのシークレットが侵害され、攻撃者が「有効な」トークンを生成した場合でも、/ loginエンドポイントを介して生成された正確なトークンのみが生成されます。受け入れられます。これは合理的ですか、それとも冗長/過剰なものですか?
2)JWT署名検証がトークンを検証する唯一の手段である場合、つまりサーバーシークレットの整合性がブレークポイントである場合、サーバーシークレットをどのように管理する必要がありますか?環境変数から読み取り、デプロイされたスタックごとに1回作成(ランダム化?)しますか?定期的に更新またはローテーションされます(その場合、ローテーション前に作成されたがローテーション後に検証する必要がある既存の有効なトークンを処理する方法。おそらく、サーバーが現在のシークレットと以前のシークレットを常に保持していれば十分です) ?他に何か?
サーバーシークレットが危険にさらされるリスクに関しては、私は単に過度に偏執的であるかもしれません。もちろん、これは、すべての暗号化の状況で対処する必要があるより一般的な問題です...
RSAPrivateKey privateKey
??