What is JWT -- JSON WEB TOKEN

What is JWT

Json web token (JWT), is a JSON-based open standard ( (RFC 7519 ) implemented for passing claims between web application environments . The token is designed to be compact and secure, especially for single distribution of distributed sites. Sign-on (SSO) scenario. The JWT statement is generally used to transfer the authenticated user identity information between the identity provider and the service provider in order to obtain resources from the resource server, and can also add some additional other business logic necessary The claim information, the token can also be used directly for authentication, or it can be encrypted.

origin

Speaking of JWT, we should talk about the difference between token-based authentication and traditional session authentication.

Traditional session authentication

We know that the http protocol itself is a stateless protocol, which means that if the user provides a user name and password to our application for user authentication, the user will have to perform user authentication again for the next request. OK, because according to the http protocol, we can't know which user made the request, so in order for our application to identify which user made the request, we can only store a copy of the user's login information on the server. This login information It will be passed to the browser in the response, telling it to save it as a cookie, so that it can be sent to our application in the next request, so that our application can identify which user the request came from. This is traditional session-based authentication.

However, this session-based authentication makes the application itself difficult to expand. With the increase of different client users, the independent server can no longer carry more users. At this time, the problem of session-based authentication application will be exposed.

Issues revealed by session-based authentication

Session : After each user is authenticated by our application, our application must make a record on the server side to facilitate the identification of the user's next request. Generally speaking, the session is stored in the memory, and with the authentication of the user's If it increases, the overhead of the server will increase significantly.

Scalability : After the user is authenticated, the server makes an authentication record. If the authentication record is stored in memory, it means that the user must request this server next time, so that the authorized resources can be obtained. In distributed applications, the capacity of the load balancer is correspondingly limited. This also means that the scalability of the application is limited.

CSRF : Because user identification is based on cookies, if cookies are intercepted, users will be vulnerable to cross-site request forgery attacks.

Token-based authentication mechanism

Similar to the http protocol, the token-based authentication mechanism is stateless, and it does not need to keep the user's authentication information or session information on the server side. This means that applications based on the token authentication mechanism do not need to consider which server the user logs in on, which facilitates application expansion.

The process is like this:

  • User requests server with username and password
  • The server authenticates the user's information
  • The server authenticates and sends a token to the user
  • The client stores the token and attaches the token value to each request
  • The server verifies the token value and returns the data

This token must be passed to the server in each request, and it should be stored in the request header. In addition, the server must support CORS(跨来源资源共享)the policy. Generally, we can do this on the server Access-Control-Allow-Origin: *.

So we now return to the topic of JWTs.

What does a JWT look like?

JWT is composed of three pieces of information, and the three pieces of information text are .linked together to form a Jwt string. like this:

eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiYWRtaW4iOnRydWV9.TJVA95OrM7E2cBab30RMHrHDcEfxjoYZgeFONFh7HgQ

Composition of JWT

The first part we call it the header, the second part we call it the payload (similar to what is carried on an airplane), and the third part is the visa (signature).

header

The header of jwt carries two parts of information:

  • Declare type, here is jwt
  • The algorithm that declares encryption usually uses HMAC SHA256 directly

The full header looks like the following JSON:

{
  'typ': 'JWT',
  'alg': 'HS256'
}

The header is then base64 encrypted (this encryption can be decrypted symmetrically), forming the first part.

eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9

playload

The payload is where the valid information is stored. The name seems to refer to the cargo carried on the plane, and these valid information consists of three parts

  • 标准中注册的声明
  • 公共的声明
  • 私有的声明

标准中注册的声明 (建议但不强制使用) :

  • iss: jwt签发者
  • sub: jwt所面向的用户
  • aud: 接收jwt的一方
  • exp: jwt的过期时间,这个过期时间必须要大于签发时间
  • nbf: 定义在什么时间之前,该jwt都是不可用的.
  • iat: jwt的签发时间
  • jti: jwt的唯一身份标识,主要用来作为一次性token,从而回避重放攻击。

公共的声明
公共的声明可以添加任何的信息,一般添加用户的相关信息或其他业务需要的必要信息.但不建议添加敏感信息,因为该部分在客户端可解密.

私有的声明
私有声明是提供者和消费者所共同定义的声明,一般不建议存放敏感信息,因为base64是对称解密的,意味着该部分信息可以归类为明文信息。

定义一个payload:

{
  "sub": "1234567890",
  "name": "John Doe",
  "admin": true
}

然后将其进行base64加密,得到Jwt的第二部分。

eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiYWRtaW4iOnRydWV9

signature

jwt的第三部分是一个签证信息,这个签证信息由三部分组成:

  • header (base64后的)
  • payload (base64后的)
  • secret

这个部分需要base64加密后的header和base64加密后的payload使用.连接组成的字符串,然后通过header中声明的加密方式进行加盐secret组合加密,然后就构成了jwt的第三部分。

// javascript
var encodedString = base64UrlEncode(header) + '.' + base64UrlEncode(payload);

var signature = HMACSHA256(encodedString, 'secret'); // TJVA95OrM7E2cBab30RMHrHDcEfxjoYZgeFONFh7HgQ

将这三部分用.连接成一个完整的字符串,构成了最终的jwt:

  eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiYWRtaW4iOnRydWV9.TJVA95OrM7E2cBab30RMHrHDcEfxjoYZgeFONFh7HgQ

注意:secret是保存在服务器端的,jwt的签发生成也是在服务器端的,secret就是用来进行jwt的签发和jwt的验证,所以,它就是你服务端的私钥,在任何场景都不应该流露出去。一旦客户端得知这个secret, 那就意味着客户端是可以自我签发jwt了。

如何应用

一般是在请求头里加入Authorization,并加上Bearer标注:

fetch('api/user/1', {
  headers: {
    'Authorization': 'Bearer ' + token
  }
})

服务端会验证token,如果验证通过就会返回相应的资源。整个流程就是这样的:


jwt-diagram

总结

优点

  • 因为json的通用性,所以JWT是可以进行跨语言支持的,像JAVA,JavaScript,NodeJS,PHP等很多语言都可以使用。
  • 因为有了payload部分,所以JWT可以在自身存储一些其他业务逻辑所必要的非敏感信息。
  • 便于传输,jwt的构成非常简单,字节占用很小,所以它是非常便于传输的。
  • 它不需要在服务端保存会话信息, 所以它易于应用的扩展

安全相关

  • 不应该在jwt的payload部分存放敏感信息,因为该部分是客户端可解密的部分。
  • 保护好secret私钥,该私钥非常重要。
  • 如果可以,请使用https协议

https://github.com/bigmeow/JWT


Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=326426831&siteId=291194637