jwt and session differences and advantages and disadvantages

Background: Authentication and Authorization difference:

Authentication: user authentication, referring to verify a user's identity, for example, you want to login as a small A, then the application needs to be confirmed by a user name and password you really are little A.

Authorization: Authorization, referring to the offer after confirming your identity you give permission, for example, small A user can modify the data, and the user can only read a small B data.

Because http protocol is stateless, each request are stateless. When a user logs on through a user name and password, his next request does not carry any state, the application can not know his identity, it must be re-certified. So we hope that every http request after the user logs in successfully, are able to save his login status.

The current mainstream user authentication methods are based on token-based session in two ways.

Based on the user authentication session

Session-based authentication process is as follows:

img

  1. Users enter their login information
  2. Server verifies the information is correct, and create a session, and then stored in the database
  3. Generate a server user sessionId, having a Cookie sesssionId placed in the user's browser.
  4. In subsequent requests, the sessionID verified against the database, if valid, the request is accepted
  5. Once the user logs off the application, the session will be destroyed at the client and server side

Based on the token (Token) user authentication

The most common is JSON Web Token (jwt):

img

  1. Users enter their login information
  2. Server verifies the information is correct, and return the signed token
  3. token stored in the client local storage such as the presence or in the cookie
  4. HTTP request after the token will be added to the request in advance
  5. Decoding the JWT server, and if the token is valid, the request is accepted
  6. Once the user logs out, the token will be destroyed at the client, does not require interaction with the server is a key token is stateless. Backend server does not need to save the current record or the session token.

The composition jwt

jwt certification principles:

A jwt is actually a string that consists of three parts, a head, a load signature, these three parts are json format.

Head (Header)

Header is used to describe the basic information about the JWT, such as its type and algorithm used for the signature.

{
  "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的场景:

  • Short period
  • Just want to be used once

For example, send an email user registration allowed to activate the account, the message typically requires a link, the link needs to have the following properties: the ability to identify the user, the link having timeliness (usually only a few hours to allow activation), It can not be tampered with in order to activate other possible accounts, disposable. This scene is suitable for use jwt.

And because of the characteristics of a disposable jwt. Single sign-on and session management is not suitable for use jwt, if additional state logical storage jwt deployed in the service side, you might as well use the session. Based session there are many mature framework out of the box, but with jwt also achieve their own logic.

Link: https: //juejin.im/post/5cefad23e51d4510774a87f4

Original articles published 0 · won praise 0 · Views 27

Guess you like

Origin blog.csdn.net/matong5418/article/details/104504981