REST APIセキュリティストアドトークンvs JWT vs OAuth


104

モバイルアプリケーションとAPIの量は日々増加しているため、REST APIを保護するための最適なセキュリティソリューションを探しています。

私はさまざまな認証方法を試しましたが、まだいくつかの誤解があるため、より経験豊富な誰かのアドバイスが必要です。

このすべてを理解する方法を教えてください。何か間違って理解した場合は、お知らせください。

REST APIが一般にWEBと同様にステートレスである限り、各リクエスト(cookies、token ....)で認証データを送信する必要があります。ユーザーを認証するために広く使用されている3つのメカニズムを知っています

  1. HTTPSを使用したトークン。私はこのアプローチを何度も使用しましたが、HTTPSで十分です。ユーザーが正しいパスワードとログインを提供すると、応答としてトークンを受け取り、それを以降のリクエストに使用します。トークンはサーバーによって生成され、保存されます。たとえば、ユーザー情報が保存される別のテーブルまたは同じテーブルに保存されます。そのため、各リクエストサーバーで、ユーザーがトークンを持っているかどうかを確認します。トークンがデータベース内と同じである場合。すべてが非常に簡単です。

  2. JWTトークン。このトークンは自己記述的であり、トークン自体に関するすべての必要な情報が含まれています。このトークンは秘密キーワードを使用してサーバーによって生成(署名)されるため、ユーザーは有効期限やその他の要求などを変更できません。これも明らかです。しかし、個人的には、トークンを無効にする方法の1つの大きな問題です。

  3. OAuth 2.サーバーとクライアント間で直接通信が確立される場合、このアプローチを使用する必要がある理由がわかりません。私の知る限り、OAuthサーバーは、他のアプリケーションがパスワードとログインを保存せずにユーザー情報にアクセスできるように、制限されたスコープでトークンを発行するために使用されます。これは、ユーザーが何らかのページでサインアップしたい場合、ソーシャルネットワークにとって優れたソリューションです。サーバーは、たとえばtwitterやfacebookからユーザー情報を取得する許可を要求し、登録フィールドにユーザーデータなどを入力できます。

オンラインストアのモバイルクライアントを検討してください。

最初の質問は、最初のタイプのトークンよりもJWTを好むべきですか?モバイルクライアントでログイン/ログアウトユーザーが必要な場合、トークンをどこかに格納する必要があります。JWTの場合、ログアウト時にトークンを無効にする必要があります。トークンを無効化するには、無効なトークンリスト(ブラックリスト)を作成する方法があります。うーん。テーブル/ファイルのサイズは、トークンがテーブルに保存されてユーザーに関連付けられ、ログアウト時に削除された場合よりもはるかに大きくなります。

それでは、JWTトークンの利点は何ですか?

OAuthに関する2番目の質問は、サーバーと直接通信する場合に使用する必要がありますか?クライアントとサーバー間のもう1つのレイヤーの目的はトークンの発行のみですが、通信はoauthサーバーではなくメインサーバーと行われます。私が理解しているように、OAuthサーバーは、ユーザーの個人情報にアクセスするためのサードパーティアプリのアクセス許可(トークン)を付与する責任があります。しかし、私のモバイルクライアントアプリケーションはサードパーティではありません。


おかげで、私は最近これを疑問に思っていました。セッション管理(ビーカー)を使用し、1時間後にセッショントークンを削除しました。Oauthは適切ではないようです。
JasTonAChair 16

回答:


86

最初のケースを検討してください。各クライアントは、セッションの期間中持続するランダムなIDを取得します。必要に応じて、数日かかることもあります。次に、そのセッションに関連する情報をサーバー側のどこかに保存します。ファイルまたはデータベースにある可能性があります。Cookieを介してIDを渡すと仮定しますが、URLまたはHTTPヘッダーを使用できます。

セッションID / Cookie

長所:

  • クライアントとサーバーの両方を簡単にコーディングできます。
  • 誰かがログアウトしたときにセッションを簡単に破棄できます。

短所:

  • サーバー側は、クライアントがログアウトしなかった期限切れのセッションを定期的に削除する必要があります。
  • すべてのHTTP要求には、データストアの検索が必要です。
  • アクティブなセッションを持つユーザーが増えると、ストレージ要件が増加します。
  • 複数のフロントエンドHTTPサーバーがある場合、保存されたセッションデータはすべてのサーバーからアクセス可能である必要があります。これは、1つのサーバーに保存するよりも少し手間がかかります。大きな問題は、データストアが単一障害点となり、ボトルネックになる可能性があることです。

JSON Webトークン(JWT)

2番目のケースでは、データはサーバーではなくJWTに保存されます。

長所:

  • サーバー側のストレージの問題はなくなりました。
  • クライアント側のコードは簡単です。

短所:

  • JWTサイズはセッションIDよりも大きくなる可能性があります。各HTTP要求に含まれているため、ネットワークのパフォーマンスに影響を与える可能性があります。
  • JWTに保存されたデータは、クライアントが読み取り可能です。これが問題になる可能性があります。
  • サーバー側では、JWTを生成、検証、読み取るためのコードが必要です。難しくはありませんが、少し学習曲線があり、セキュリティはそれに依存します。

    署名キーのコピーを取得した人は誰でもJWTを作成できます。これがいつ起こるかわからないかもしれません。

    一部のライブラリにはバグがあり、「none」アルゴリズムで署名されたJWTを受け入れたため、誰でもサーバーが信頼できるJWTを作成できました。

  • JWTの有効期限が切れる前に取り消すには、取り消しリストを使用する必要があります。これにより、回避しようとしていたサーバー側のストレージの問題に戻ります。

OAuth

多くの場合、OAuthは認証(つまりID)に使用されますが、ユーザーが購入してダウンロードする資格のあるコンテンツのリストなど、他のデータを共有するために使用できます。また、サードパーティによって保存されたデータへの書き込みアクセスを許可するためにも使用できます。OAuthを使用してユーザーを認証してから、セッションデータにサーバー側ストレージまたはJWTを使用できます。

長所:

  • ユーザーがサインアップまたはパスワードをリセットするためのコードはありません。
  • 検証リンク付きのメールを送信してからアドレスを検証するコードはありません。
  • ユーザーは、別のユーザー名とパスワードを覚えたり書き留めたりする必要はありません。

短所:

  • ユーザーがサービスを使用するには、サードパーティに依存します。彼らのサービスがダウンしたり、彼らがそれを中止した場合、あなたは何か他のものを把握する必要があります。たとえば、ユーザーのIDが "foo@a.com"から "bar@b.com"に変更された場合、どのようにユーザーのアカウントデータを移行しますか?
  • 通常、プロバイダーごとにコードを作成する必要があります。例:Google、Facebook、Twitter。
  • あなたまたはあなたのユーザーはプライバシーの問題を抱えているかもしれません。プロバイダーは、どのユーザーがサービスを使用するかを知っています。
  • プロバイダーを信頼しています。プロバイダーは、あるユーザーに有効なトークンを他の誰かに発行することができます。これは合法的な目的であってもなくてもかまいません。

雑多

  • セッションIDとJWTの両方をコピーして、複数のユーザーが使用できます。クライアントIPアドレスをJWTに保存して検証できますが、これにより、クライアントがWi-Fiからセルラーへのローミングを防止できます。

答えに追加すると、ユーザーがソーシャルネットワーキングWebサイトやGoogleのいずれとも通常関連付けられていない、またはリンクされていない企業アカウントを使用してサインアップしたい場合、oAuthは役に立たない可能性があります。
アフタブNaveed

5
なぜこれが受け入れられた答えなのか分かりませんか?それだけで、他の方法で問題を改質し、本当の問題に答えていない
AMD

1
あなたは言います:「JWTに保存されたデータはクライアントによって読み取り可能です。これは問題かもしれません。それが問題ならJWEを使用しないのはなぜですか?
Silver

この答えは、リンゴとオレンジを混同します。これらをOAuth 2.0(「承認」仕様)と比較しないでください。OPが知る必要があるのは、「リソース所有者のパスワードフロー」です。これは許可としての認証です。
オヌルユルドゥルム

5

元のトークンを無効にする必要がある理由を自問してください。

ユーザーがログインし、トークンが生成されてアプリがオフになります。

ユーザーがログアウトを押すと、新しいトークンが生成され、元のトークンが置き換えられます。もう一度、すべてが順調です。

両方のトークンがうろうろしている場合を心配しているようです。ユーザーがログアウトし、ログイントークンを使用して何らかの方法でリクエストを行うとどうなりますか。このシナリオはどの程度現実的ですか?ログアウト中の問題だけですか、複数のトークンが問題になる可能性のあるシナリオがたくさんありますか?

私自身、心配する価値はないと思います。誰かが暗号化されたhttpsデータをインターセプトおよびデコードしている場合、さらに大きな問題が発生します。

元のトークンに有効期限を設定することにより、保護を強化できます。だから、盗まれたり何かになってしまったら、それは短期間しか役に立たないでしょう。

それ以外の場合は、サーバーに状態情報が必要だと思います。トークンをブラックリストに登録するのではなく、現在のトークンの署名をホワイトリストに登録します。


2
一部のクライアントが悪意があると仮定した場合、セッションがコピーされて再利用されることが容易にわかり、サーバーでこれに対抗する必要があります。
マイケルショー

1
悪い考え、これはハッカーが後で使用するか、単に強引に強制することができます
...-CROSP

2
ユーザーが他のすべてのデバイスからログアウトしたい場合、JWTを使用することはできません。
amd

@amdは不可能ですか?nonce =(random)を追加し、ユーザーがログアウトした場合、nonceを置き換えるとどうなりますか。シンプルで効果的なようです。
サイモンB.

3

ユーザーとともにソルト値を保存し、ユーザーのトークンの一部としてソルトを使用することで、言及したJWTの問題を処理できます。次に、トークンを無効にする必要がある場合は、ソルトを変更します。

私はそれが数年であったことを知っています、しかし私は実際にこれを実際に今違うものにするでしょう。アクセストークンの寿命は比較的短く、たとえば1時間であることを確認すると思います。また、サーバーでステートフルなリフレッシュトークンを使用し、誰かのセッションを終了したい場合は、サーバーから削除してリフレッシュトークンを無効にします。その後、1時間後にユーザーはログアウトされ、再度ログインしてアクセスを回復する必要があります。


4
しかし、再び、それはこの場合には状態いっぱいになったので、何が塩を作成したり、他のアプローチを使用する理由である、あなたがテーブルでシンプルな店舗トークンすることができますし、それを無効にする必要があるとき削除
CROSP

2
時間に基づいて無効化することもできます。
RibaldEddie

この場合の有効期限の違いは何ですか?ユーザーがモバイルクライアントからログアウトする時間に基づいてトークンを無効にするにはどうすればよいですか?この場合、APIがステートレスになる方法はないようです。最も適切で安全なソリューションは何ですか?
クロス

2
単一のデバイスからのログアウトに最も適しているのは、ソルトに加えてclientIdを使用することです。洞察のためにOauth-jwtベアラートークンの仕様を確認することをお勧めします。
RibaldEddie

答えてくれてありがとう。しかし、この場合になぜOAuthを使用する必要があるのか​​まったくわかりません。
クロス
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.