jwt, json web token

1. JWT

  1. What is JWT

    1. The official definition of json web token is an open standard (rfc7519), which defines a compact and self-contained way for the secure transmission of information between parties as JSON objects. This information can be verified and trusted because it It is digitally signed. jwt can use secret (using HMAC algorithm) or use RSA or ECDSA public key, private key to sign.
    2. In common explanation, JWT is referred to as JSON Web Token, which is used as a token in web applications in JSON form, which is used to securely transmit information as JSON objects between parties. Data encryption and signatures can also be completed during the transmission process. deal with.
  2. What can JWT do

    1. Authorization
      1. This is the most common solution using JWT. Once the user logs in successfully, the system generates a JWT and passes it to the user. Each subsequent request will include the JWT, allowing the user to access the routes, services and resources allowed by the token. Single sign-on is a feature of JWT that is widely used today because it has a small overhead and can be easily used in different domains.
    2. Information exchange
      1. JSON Web Token is a good way to transfer information securely between parties, because the JWT can be signed, so you can be sure that the sender is who said it. In addition, since the signature is calculated using the header and payload, you can also verify whether the content has been tampered with.
  3. Why use JWT

    1. Based on traditional session authentication

      1. We know that the http protocol itself is a stateless protocol, and this means that if the user provides a user name and password to our application for user authentication, the next time the user requests it, the user will have to perform user authentication again. , Because according to the http protocol, we cannot know which user made the request, so in order for our application to explain which user made the request, we can only store a user login information on the server. This login information will In response, it is passed to the browser and told to save it as a cookie, so that
        it can be sent to our application when the next request is made, so that our application can identify which user the request comes from. This is the traditional session-based authentication
    2. Certification process

      1. cookie session
    3. Exposed issues

      1. After each user is authenticated by our application, our application must make a record in the service to facilitate the user's next request. Generally speaking, the session is stored in memory, and as the number of authenticated users increases, the server The cost will increase significantly
      2. After the user is authenticated, the server makes an authentication record. If the authentication record is stored in the memory, this means that the next request of the user must also be requested on this server, so that the authorized source can be obtained, which is distributed In the form of applications, the corresponding load balancing ability is limited, which also means that the application's scalability is limited.
      3. Because the user identification is based on cookies, if the cookie is intercepted, the user will be vulnerable to cross-site request forgery attacks
      4. It is even more painful in the front-end and back-end separation system: the front-end and back-end separation increases the complexity of deployment after the application is decoupled.Usually, the user has to forward multiple requests for one request. Information, if there are many users at the same time, this information is stored in the memory of the server, which increases the burden on the server, and there is CSRF (cross-site request forgery attack, session is based on cookie for user identification, if cookie is intercepted, user will be very It is vulnerable to cross-site request forgery attacks, and the
        sessionid is a characteristic value, and the expressed information is not rich enough, and it is not easy to expand, and if your back-end application is multi-node deployment, then you need to implement a session sharing mechanism, which is not convenient for clustering application
    4. Based on JWT authentication

      1. Certification process

      1. Certification process

        1. First, send your username and password to the back-end interface through the form. This process is generally an HTTP POST request. The method is built through SSL encrypted transmission (https protocol) to avoid sensitive information being sniffed.
        2. After the back-end successfully checks the username and password, it uses the user's id and other information as the JWT Payload (load), and bas64 encodes it and the header separately and signs it to form a JWT (Token). The formed JWT is the same. 111.zzz, xxx string
        3. token head. payload. singurater
        4. The back end returns the JWT as the result of a successful login to the front end. The front end can save the returned result in localStorage or sessionStorage, and the front end can delete the saved JWT when logging out.
        5. The front end puts the JWT into the Authorization bit in the Http Header every time a request, (solves XSS and XSRF problems) HEADER
        6. The backend checks whether it exists, and if it exists, it verifies the validity of the JWT, for example, to check whether the signature is correct: Check whether the Token is expired: Check whether the recipient of the Token is himself (optional)
        7. After the verification is passed, the backend uses the user information contained in the JWT to perform other logical operations and returns the corresponding results.
      2. JWT advantage

        1. Concise: It can be sent through URL, POST parameters or in HTTP header, because the amount of data is small and the transmission speed is very fast
        2. Self-contained: the load contains all the information needed by the user, avoiding multiple queries to the database
        3. Because Token is stored on the client in the form of JSON encryption, JWT is cross-language, and in principle, any web format is supported
        4. There is no need to save session information on the server, which is especially suitable for distributed microservices.
  4. JWT structure

    1. Token composition

      1. Header
      2. Payload
      3. Signature (Sionature)
        Therefore, JWT usually looks like this: xxx.yyy.zzz
    2. The Header
      header usually consists of two parts: the type of token (that is, the JWT and the signature algorithm used, such as HMAC SHA256 or RSA, which will make the Base64 encoding form the first part of the JWT structure.
      Note: Base64 is a kind of encoding, also In other words, it can be translated back to its original appearance. It is not an encryption process

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

    3. The second part of the Payload token is the payload, which contains claims, which are claims about entities (usually users) and other data. Similarly, it will use Base64 encoding to form
      the second part of the JWT structure

      {
              
              
          "id":666,
          "name":"bitqian666",
          "age":19
      }
      
    4. The
      first two parts of Signature are encoded using Base64, that is, the front-end can unlock the information inside. Signature needs to use the encoded header and payload and a key we provide, and then use the signature algorithm specified in the header (HS256) Sign, the role of the signature is to ensure that the JWT has not been changed by Mu

    5. Signing purpose The
      last step of signing is actually to sign the header and payload content to prevent the content from being tampered with. If someone modifies the header and the content of the payload after decoding it, then encodes it, and finally adds the previous signature combination to form a new JWT, then the server will determine that the signature formed by the new header and payload is attached to the JWT. The signature is different.
      If you want to sign the new header and payload, if you don’t know the key used when the server is encrypted, the resulting signature is also different.

    6. Information Security Issues
      Everyone will definitely ask a question here: Base64 is a kind of encoding and is reversible, then my information will be exposed?
      Yes. Therefore, in JWT, no sensitive data should be added to the load. For example, what we are transmitting is the User ID of the user. This value is actually not sensitive content, and it is generally safe to be known. But content like passwords cannot be placed in JWT. If you put the user's password in the JWT, a malicious third party can quickly know your password through Base64 decoding. Therefore, JWT is suitable for delivering some non-sensitive information to Web applications. JWT is also often used to design user authentication and authorization systems, and even implement single sign-on for web applications.

  5. JWT issues and trends

    1. JWT is not encrypted by default, but it can be encrypted. After generating the original token, you can use the changed token to encrypt it again.
    2. When JWT is not encrypted, some private data cannot be transmitted through JWT.
    3. JWT can be used not only for authentication, but also for information exchange. Making good use of JWT helps reduce the number of server requests to the database.
    4. The biggest disadvantage of JWT is that the server does not save the session state, so it is impossible to cancel the token or change the permissions of the token during use. In other words, once the JWT is issued, it will remain valid during the validity period.
    5. JWT itself contains authentication information, so once the information is leaked, anyone can get all the permissions of the token. In order to reduce embezzlement, the validity period of JWT should not be set too long. For some important operations, users should be authenticated every time they use them.
    6. Refresh the JWT senselessly, the backend receives the JWT analysis to obtain the expiration time, if it is about to expire, a new token is generated (the business data is the same as before)
    7. In order to reduce embezzlement and theft, JWT does not recommend the use of HTTP protocol to transmit code, but the use of encrypted HTTPS protocol for transmission.

2. jwt encryption and decryption tool, use

pom

 <!-- https://mvnrepository.com/artifact/com.auth0/java-jwt -->
 <dependency>
     <groupId>com.auth0</groupId>
     <artifactId>java-jwt</artifactId>
     <version>3.10.3</version>
 </dependency>

Tools

package top.bitqian.config;

import com.auth0.jwt.JWT;
import com.auth0.jwt.JWTVerifier;
import com.auth0.jwt.algorithms.Algorithm;
import com.auth0.jwt.interfaces.Claim;
import com.auth0.jwt.interfaces.DecodedJWT;

import java.util.Calendar;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;


/**
 * @author echo lovely
 * @date 2020/12/4 21:46
 */

public class JwtUtil {
    
    

    //密钥(不能泄露 、可多次加盐加密再存在合适的地方)
    public static final String SECRET = "defAu&TJHVhc$%WW^JJG";
    //过期时间:秒
    public static final int EXPIRE = 300;

    /**
     * JWT 添加至HTTP HEAD中的前缀
     */
    private static final String JWT_SEPARATOR = "Bearer ";

    /**
     * 生成Token
     * @param  userName userName
     * @param userPwd userPwd
     * @return token token
     * @throws Exception create token ex
     */
    public static String createToken(String userName, String userPwd) throws Exception {
    
    

       try {
    
    
           //日历对象
           //当前时间
           Calendar nowTime = Calendar.getInstance();
           //加30秒
           nowTime.add(Calendar.SECOND, EXPIRE);
           Date expireDate = nowTime.getTime();

           //标头 可以不写,默认值就是下方所定义的map
           Map<String, Object> map = new HashMap<>();
           // 算法
           map.put("alg", "HS256");
           // 类型 jwt加密
           map.put("typ", "JWT");

           return  JWT.create()
                   .withHeader(map)//头 有默认值 可以不写

                   //负载 业务数据
                   .withClaim("userPwd", userPwd)
                   .withClaim("userName", userName)
                   .withClaim("myId", "aa")
                   .withSubject("subject")//可以不写
                   .withIssuedAt(new Date())//签名时间
                   .withExpiresAt(expireDate)//过期时间
                   .sign(Algorithm.HMAC256(SECRET));//签名
       } catch (Exception e) {
    
    
           throw new Exception(e);
       }

    }

    /**
     * 验证Token
     * @param token token
     * @return token map
     * @throws RuntimeException 凭证已过期,请重新登录
     */
    public static Map<String, Claim> verifyToken(String token) throws RuntimeException {
    
    
        JWTVerifier verifier = JWT.require(Algorithm.HMAC256(SECRET)).build();
        DecodedJWT jwt;
        try {
    
    
            jwt = verifier.verify(token);
        }catch (Exception e){
    
    
            throw new RuntimeException("凭证已过期,请重新登录");
        }
        return jwt.getClaims();
    }

    /**
     * 解析Token
     * @param token token
     * @return claim
     */
    public static Map<String, Claim> parseToken(String token){
    
    
        DecodedJWT decodedJWT = JWT.decode(token);
        return decodedJWT.getClaims();
    }

}


test

    public static void main(String[] args){
    
    
        try {
    
    
        	// 创建token,传入参数
            String token = JwtUtil.createToken("your token param", "your token param");
            // 获取token
            System.out.println("token=" + token);
            //Thread.sleep(5000);
            Map<String, Claim> map = JwtUtil.verifyToken(token);
            //Map<String, Claim> map = JwtUtil.parseToken(token);
            //遍历
            for (Map.Entry<String, Claim> entry : map.entrySet()){
    
    
                if (entry.getValue().asString() != null){
    
    
                    System.out.println(entry.getKey() + "===" + entry.getValue().asString());
                }else {
    
    
                    System.out.println(entry.getKey() + "===" + entry.getValue().asDate());
                }
            }
        }catch (Exception e){
    
    
            e.printStackTrace();
        }
    }

Guess you like

Origin blog.csdn.net/qq_44783283/article/details/110733899