JWTとセッションの違いと長所と短所

背景:認証と承認の違い:

認証:ユーザー認証、ユーザーの身元を確認するために参照して、たとえば、あなたは小さなAとしてログインしたい場合、アプリケーションは、あなたが本当に少しA.あるユーザ名とパスワードによる確認が必要

認証:認証、例えば、小さなAのユーザーがデータを変更することができ、あなたが許可を与え、あなたの身元を確認した後に提供するために参照すると、ユーザーはわずかBのデータを読み取ることができます。

HTTPプロトコルはステートレスであるため、各リクエストはステートレスです。ユーザー名とパスワードによるユーザーがログオンが、彼の次の要求がどのような状態を有していない場合は、自分のアイデンティティを知ることができないアプリケーションは、それが再認定を受けなければなりません。我々は成功し、ユーザーがログインした後、そのすべてのHTTP要求を願っていますので、彼のログイン状態を保存することができます。

現在主流のユーザ認証方法は、2つの方法でトークンベースのセッションに基づいています。

ユーザーの認証セッションに基づいて、

次のようにセッションベースの認証プロセスは次のとおりです。

IMG

  1. ユーザーは、ログイン情報を入力します。
  2. サーバーは、情報が正しいことを確認し、セッションを作成し、データベースに保存されています
  3. ユーザーのブラウザに配置されたクッキーsesssionIdを持つ、サーバーのユーザーセッションIDを生成します。
  4. 、要求が受け入れられる有効な場合、後続の要求では、セッションIDは、データベースに対して検証しました
  5. ユーザーがアプリケーションをログオフすると、セッションは、クライアントとサーバー側では破壊されます

トークン(トークン)、ユーザ認証に基づいて、

最も一般的なのは、JSONウェブトークン(JWT)です。

IMG

  1. ユーザーは、ログイン情報を入力します。
  2. サーバーの検証情報が正しい、と署名したトークンを返します
  3. そのような存在として、あるいはクッキーにクライアントのローカルストレージに保存されたトークン
  4. トークンの後のHTTPリクエストは、事前にリクエストに追加されます
  5. JWTサーバをデコードし、トークンが有効であれば、要求が受け入れられています
  6. ユーザーがログアウトすると、トークンがクライアントで破壊されると、サーバとの相互作用がキートークンがステートレスである必要はありません。バックエンドサーバは、現在のレコードまたはセッション・トークンを保存する必要はありません。

組成JWT

JWTの認定の原則:

JWTは、実際には3つの部分、頭部、負荷署名から成る文字列であり、これら3つの部分がJSON形式です。

ヘッド(ヘッダー)

ヘッダは、署名に使用されるタイプとアルゴリズムとして、JWTの基本情報を記述するために使用されます。

{
  "typ": "JWT",
  "alg": "HS256"
}
复制代码

在这里,我们说明了这是一个JWT,并且我们所用的签名算法是HS256算法。

载荷(Payload)

载荷可以用来放一些不敏感的信息。

{
    "iss": "John Wu JWT",
    "iat": 1441593502,
    "exp": 1441594722,
    "aud": "www.example.com",
    "sub": "[email protected]",
    "from_user": "B",
    "target_user": "A"
}
复制代码

这里面的前五个字段都是由JWT的标准所定义的。

  • iss: 该JWT的签发者
  • sub: 该JWT所面向的用户
  • aud: 接收该JWT的一方
  • exp(expires): 什么时候过期,这里是一个Unix时间戳
  • iat(issued at): 在什么时候签发的 把头部和载荷分别进行Base64编码之后得到两个字符串,然后再将这两个编码后的字符串用英文句号.连接在一起(头部在前),形成新的字符串:
eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJmcm9tX3VzZXIiOiJCIiwidGFyZ2V0X3VzZXIiOiJBIn0
复制代码

签名(signature)

最后,我们将上面拼接完的字符串用HS256算法进行加密。在加密的时候,我们还需要提供一个密钥(secret)。加密后的内容也是一个字符串,最后这个字符串就是签名,把这个签名拼接在刚才的字符串后面就能得到完整的jwt。header部分和payload部分如果被篡改,由于篡改者不知道密钥是什么,也无法生成新的signature部分,服务端也就无法通过,在jwt中,消息体是透明的,使用签名可以保证消息不被篡改。

eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJmcm9tX3VzZXIiOiJCIiwidGFyZ2V0X3VzZXIiOiJBIn0.rSWamyAYwuHCo7IFAgd1oRpSP7nzL7BF5t7ItqpKViM
复制代码

区别和优缺点:

基于session和基于jwt的方式的主要区别就是用户的状态保存的位置,session是保存在服务端的,而jwt是保存在客户端的。

jwt的优点:

  1. 可扩展性好 应用程序分布式部署的情况下,session需要做多机数据共享,通常可以存在数据库或者redis里面。而jwt不需要。
  2. 无状态 jwt不在服务端存储任何状态。RESTful API的原则之一是无状态,发出请求时,总会返回带有参数的响应,不会产生附加影响。用户的认证状态引入这种附加影响,这破坏了这一原则。另外jwt的载荷中可以存储一些常用信息,用于交换信息,有效地使用 JWT,可以降低服务器查询数据库的次数。

jwt的缺点:

  1. 安全性

由于jwt的payload是使用base64编码的,并没有加密,因此jwt中不能存储敏感数据。而session的信息是存在服务端的,相对来说更安全。

  1. 性能

jwt太长。由于是无状态使用JWT,所有的数据都被放到JWT里,如果还要进行一些数据交换,那载荷会更大,经过编码之后导致jwt非常长,cookie的限制大小一般是4k,cookie很可能放不下,所以jwt一般放在local storage里面。并且用户在系统中的每一次http请求都会把jwt携带在Header里面,http请求的Header可能比Body还要大。而sessionId只是很短的一个字符串,因此使用jwt的http请求比使用session的开销大得多。

  1. 一次性

无状态是jwt的特点,但也导致了这个问题,jwt是一次性的。想修改里面的内容,就必须签发一个新的jwt。

(1)无法废弃 通过上面jwt的验证机制可以看出来,一旦签发一个jwt,在到期之前就会始终有效,无法中途废弃。例如你在payload中存储了一些信息,当信息需要更新时,则重新签发一个jwt,但是由于旧的jwt还没过期,拿着这个旧的jwt依旧可以登录,那登录后服务端从jwt中拿到的信息就是过时的。为了解决这个问题,我们就需要在服务端部署额外的逻辑,例如设置一个黑名单,一旦签发了新的jwt,那么旧的就加入黑名单(比如存到redis里面),避免被再次使用。

(2)续签 如果你使用jwt做会话管理,传统的cookie续签方案一般都是框架自带的,session有效期30分钟,30分钟内如果有访问,有效期被刷新至30分钟。一样的道理,要改变jwt的有效时间,就要签发新的jwt。最简单的一种方式是每次请求刷新jwt,即每个http请求都返回一个新的jwt。这个方法不仅暴力不优雅,而且每次请求都要做jwt的加密解密,会带来性能问题。另一种方法是在redis中单独为每个jwt设置过期时间,每次访问时刷新jwt的过期时间。

可以看出想要破解jwt一次性的特性,就需要在服务端存储jwt的状态。但是引入 redis 之后,就把无状态的jwt硬生生变成了有状态了,违背了jwt的初衷。而且这个方案和session都差不多了。

总结

适合使用jwt的场景:

  • 短い期間
  • 一度だけ使用したいです

たとえば、アカウントをアクティブにするために許可された電子メールのユーザー登録を送信、メッセージは通常、リンクを必要とし、リンクには次の特性を持っている必要があります:ユーザーを識別する能力を、適時性を持つリンク(通常は数時間活性化を可能にするために)、それは使い捨て、他の可能なアカウントを活性化するために改ざんすることはできません。このシーンは、使用JWTに適しています。

そして、理由は使い捨てJWTの特性。シングルサインオンとセッション管理が使用JWTには適していません、追加の状態論理ストレージJWTは、サービス側で展開されている場合、あなたにもセッションを使用する場合があります。ベースのセッションがあり、多くの成熟したフレームワークは、箱から出していますが、JWTでも、独自のロジックを実現します。

リンクします。https://juejin.im/post/5cefad23e51d4510774a87f4

オリジナルの記事は、0を発表 ウォンの賞賛0 ビュー27

おすすめ

転載: blog.csdn.net/matong5418/article/details/104504981