Vue_12_Spa_ Project 6 times - JWT

Keywords: Front-end Vue.js

1, Causes and working principle of jwt

1. What is JWT
     JSON Web Token (JWT), which is currently the most popular cross domain authentication solution
    

2. Why JWT
     The essence of JWT is "decentralization", and the data is stored on the client.

3. Working principle of JWT
    1. After server authentication, a JSON object will be generated and sent back to the user, as shown in the following example:
    {"UserName": "Chongchong","Role": "Admin","Expire": "2018-08-08 20:15:56"}
       2. Then, when the user communicates with the server, the client sends back the JSON object in the request
    3. In order to prevent the user from tampering with the data, the server will add a signature when generating the object and verify the returned data

4. JWT composition
     A JWT is actually a string, which consists of three parts: header, payload and signature              (signature)
     Schematic diagram of JWT structure: see "JWT data structure. jpg"
     Actual structure of JWT: eyJhbGciOiJIUzI1NiJ9
                                                 eyJzdWIiOiJ7fSIsImlzcyI6InpraW5nIiwiZXhwIjoxNTYyODUwMjM3LCJpYXQiOjE1NjI4NDg0MzcsImp0aSI6ImM5OWEyMzRmMDc4NzQyZWE4YjlmYThlYmYzY2VhNjBlIiwidXNlcm5hbWUiOiJ6c3MifQ.
             WUfqhFTeGzUZCpCfz5eeEpBXBZ8-lYg1htp-t7wD3I4
      It is a very long string, separated into three parts by dots (.). Note that there is no newline inside JWT. This is just for        For ease of presentation, write it in a few lines.
     In one line, it looks like the following: Header.Payload.Signature


 4.1 Header
     {"typ":"JWT","alg":"HS256"}
      The typ attribute in this json is used to identify that the entire token string is a JWT string; Its alg attribute is used to describe the signature and digest algorithm used when issuing the JWT
      The full names of typ and alg attributes are actually type and algorithm, which mean type and algorithm respectively. The reason why they are all represented by three letters is also based on the final string size of JWT              Worry,
      At the same time, it is consistent with the name of JWT, so it is all three characters... typ and alg are the attribute names specified in the JWT standard

  4.2 payload
     {"sub":"123","name":"Tom","admin":true}
      payload is used to carry the data to be transferred. Its json structure is actually a set of declarations for the data to be transferred by JWT. These declarations are called claims by the JWT standard,
      Its "attribute value pair" is actually a claim,
      Each claim represents a specific meaning and function.
      
  4.3 signature
      Signature is the two strings obtained by base64url encoding the json structure corresponding to the header and payload, which are spliced with English sentence point numbers, and then specified according to the alg in the header        Generated by the signature algorithm.
      
      Different algorithms lead to different signature results. Take alg: HS256 as an example to illustrate how the previous signature is obtained.
     
5. Verification process of JWT
     Its verification method is actually very simple. As long as you decode the header base64url, you can know what algorithm JWT uses to make the signature, and then use this algorithm to use the same logic again          Header and payload sign once,
     And compare whether the signature is exactly the same as the string of the third part contained in the JWT itself. As long as it is different, it can be considered that the JWT is a tampered string, which naturally belongs to verification failure        Yes.
      The receiver must use the same key as the JWT sender when generating the signature
    Note 1: when verifying a JWT, signature authentication will be done automatically by each implementation library, but the authentication of payload is determined by the user. Because JWT may contain a custom        claim,
    
    Therefore, it will not automatically verify these claim s. Take jjwt-0.7.0.jar as an example:
      A if the signature authentication fails, the following exception will be thrown:
       io.jsonwebtoken.SignatureException: JWT signature does not match locally computed signature. JWT validity cannot be asserted and should not be trusted.

    That is, the signature is wrong. The signature of JWT does not match the signature of the local computer  
        B JWT expiration exception
          io.jsonwebtoken.ExpiredJwtException: JWT expired at 2017-06-13T11:55:56Z. Current time: 2017-06-13T11:55:57Z, a difference of 1608 milliseconds.  Allowed

    Note 2: if authentication fails, 401 Unauthorized response is returned

    Note 3: as a Middleware HOOK, the authentication service intercepts the request. First, look up the Token information in the cookie. If it is not found, it will be in HTTP Authorization        Find in Head

6. JWT token refresh idea
     6.1 after successful login, return the generated JWT token to the client through the response header
    
        6.2 each time the web app project requests background data (bring the JWT token from the request header),
    If the verification is passed, refresh the JWT, save it in the response header and return it to the client. The effective time is 30 minutes
    JwtFilter
    Note 1: modify CorsFilter and add a new request header "jwt" allowed
     Note 2: originally, on the default request, the browser can only access the following default response headers
     Cache-Control
     Content-Language
     Content-Type
     Expires
     Last-Modified
     Pragma
      If you want the browser to access other response headers, you need to set access control expose headers on the server
     Access-Control-Expose-Headers : 'jwt' 
        // CorsFilter allows the client to send a new request header jwt
        resp.setHeader("Access-Control-Allow-Headers", "Origin,X-Requested-With, Content-Type, Accept, jwt");
    Note 3: axios obtains the jwt token from the response header and saves it to vuex
      Here is a problem: how to obtain the root instance of Vue in the project. The solution: modify main.js
     window.vm = new Vue({...});

The access restrictions of traditional development on resources are illustrated by using session:

Problems and mechanisms solved by jwt:

 

web.xml: filters to solve jwt problems:

<!-- solve jwt Problem filter -->
    <filter>
        <filter-name>jwtFilter</filter-name>
        <filter-class>com.zking.vue.util.JwtFilter</filter-class>
    </filter>
    <filter-mapping>
        <filter-name>jwtFilter</filter-name>
        <url-pattern>/*</url-pattern>
    </filter-mapping>

JwtFilter.java: enable jwt token verification function:

private boolean OFF = false;//true turns off jwt token verification, and false turns on

 

package com.zking.vue.util;

import java.io.IOException;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import io.jsonwebtoken.Claims;

/**
 * * JWT Verify the filter, configuration sequence: corsfilte -- > jwtfilter -- > Struts2 central controller
 * 
 * @author Administrator
 *
 */
public class JwtFilter implements Filter {

	// Excluded URL, usually the login URL (please change it to your own login URL)
	private static String EXCLUDE = "^/vue/userAction_login\\.action?.*$";

	private static Pattern PATTERN = Pattern.compile(EXCLUDE);

	private boolean OFF = false;//true turns off jwt token verification, and false turns on

	@Override
	public void init(FilterConfig filterConfig) throws ServletException {
	}

	@Override
	public void destroy() {
	}

	@Override
	public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
			throws IOException, ServletException {
		HttpServletRequest req = (HttpServletRequest) request;
		HttpServletResponse resp = (HttpServletResponse) response;
		String path = req.getServletPath();
		if (OFF || isExcludeUrl(path)) {// Landing direct release
			chain.doFilter(request, response);
			return;
		}

		// Get the token from the client request header and verify it
		String jwt = req.getHeader(JwtUtils.JWT_HEADER_KEY);
		Claims claims = this.validateJwtToken(jwt);
		if (null == claims) {
			// resp.setCharacterEncoding("UTF-8");
			resp.sendError(403, "JWT The token has expired or expired");
			return;
		} else {
			String newJwt = JwtUtils.copyJwt(jwt, JwtUtils.JWT_WEB_TTL);
			resp.setHeader(JwtUtils.JWT_HEADER_KEY, newJwt);
			chain.doFilter(request, response);
		}
	}

	/**
	 * Verify the jwt token by returning the declaration (including public and private). If null is returned, the verification fails
	 */
	private Claims validateJwtToken(String jwt) {
		Claims claims = null;
		try {
			if (null != jwt) {
				claims = JwtUtils.parseJwt(jwt);
			}
		} catch (Exception e) {
			e.printStackTrace();
		}
		return claims;
	}

	/**
	 * Is this an excluded URL
	 * 
	 * @param path
	 * @return
	 */
	private boolean isExcludeUrl(String path) {
		Matcher matcher = PATTERN.matcher(path);
		return matcher.matches();
	}

	// public static void main(String[] args) {
	// String path = "/sys/userAction_doLogin.action?username=zs&password=123";
	// Matcher matcher = PATTERN.matcher(path);
	// boolean b = matcher.matches();
	// System.out.println(b);
	// }

}

Useraction. Java: insert jwt token into response header

//				Map<String, Object> claims = new HashMap<String, Object>();
//				claims.put("uname",user.getUname());
//				claims.put("pwd", user.getPwd());
//				String jwt = JwtUtils.createJwt(claims, JwtUtils.JWT_WEB_TTL);
//				response.setHeader(JwtUtils.JWT_HEADER_KEY, jwt);
package com.zking.vue.web;
 
import java.util.HashMap;
import java.util.Map;
 
import com.fasterxml.jackson.databind.ObjectMapper;
import com.opensymphony.xwork2.ModelDriven;
import com.zking.base.web.BaseAction;
import com.zking.vue.biz.UserBiz;
import com.zking.vue.entity.User;
import com.zking.vue.util.JsonData;
import com.zking.vue.util.JwtUtils;
import com.zking.vue.util.PageBean;
import com.zking.vue.util.ResponseUtil;
import com.zking.vue.util.StringUtils;
 
public class UserAction extends BaseAction implements ModelDriven<User>{
 
	private UserBiz userBiz;
	private User user = new User();
 
	public UserBiz getUserBiz() {
		return userBiz;
	}
 
	public void setUserBiz(UserBiz userBiz) {
		this.userBiz = userBiz;
	}
	 
	public String login() {
		ObjectMapper om = new ObjectMapper();
		JsonData jsonData = null;
		try {
			if(StringUtils.isBlank(user.getUname()) || StringUtils.isBlank(user.getPwd())) {
				jsonData = new JsonData(0, "User or password is empty", user);
			}else {
				User u = this.userBiz.login(user);
				Map<String, Object> claims = new HashMap<String, Object>();
				claims.put("uname",user.getUname());
				claims.put("pwd", user.getPwd());
				String jwt = JwtUtils.createJwt(claims, JwtUtils.JWT_WEB_TTL);
				response.setHeader(JwtUtils.JWT_HEADER_KEY, jwt);
				jsonData = new JsonData(1, "Login succeeded", u);
			}
		} catch (Exception e) {
			e.printStackTrace();
			jsonData = new JsonData(0, "User or password error", user);
		}finally {
			try {
				ResponseUtil.write(response, om.writeValueAsString(jsonData));
			} catch (Exception e) {
				e.printStackTrace();
			}
		}
		
		return null;
	}
	
	public String getAsyncData() {
		ObjectMapper om = new ObjectMapper();
		try {
			Thread.sleep(6000);
			ResponseUtil.write(response, om.writeValueAsString("http://www.javaxl.com"));
		} catch (Exception e) {
			e.printStackTrace();
		}
		return null;
	}
 
	@Override
	public User getModel() {
		return user;
	}
}

 

403 error:

1. Restricted, restricted access and did not get the voucher;

2. It will also appear when you are a crawler. The IP is blocked and there is no certificate;

3. Being blacklisted;

 

 

The jwt token response header is in the browser, and the front-end code is not obtained

The front-end project http.js gets all the response header information:

// Response interceptor
axios.interceptors.response.use(function(response) {
	// debugger;
	// var jwt = response.headers['jwt'];
	// if(jwt){
	// 	window.vm.$store.commit('setJwt',{jwt:jwt});
	// }
	return response;
}, function(error) {
	return Promise.reject(error);
});
/**
 * vue Project global configuration for axios
 */
import axios from 'axios'
import qs from 'qs'

//The action module is introduced and added to the class attribute urls of axios
import action from '@/api/action'
axios.urls = action

// axios default configuration
axios.defaults.timeout = 10000; // Timeout
// axios.defaults.baseURL = 'http://localhost:8080/j2ee15 '; //  Default address
axios.defaults.baseURL = action.SERVER;

//Organize data
// Only applicable to POST,PUT,PATCH, transformRequest ` allows you to modify the request data before sending it to the server
axios.defaults.transformRequest = function(data) {
	data = qs.stringify(data);
	return data;
};


// request interceptor 
axios.interceptors.request.use(function(config) {
	var jwt = window.vm.$store.getters.getJwt;
	config.headers['jwt'] = jwt;
	return config;
}, function(error) {
	return Promise.reject(error);
});

// Response interceptor
axios.interceptors.response.use(function(response) {
	// debugger;
	var jwt = response.headers['jwt'];
	if(jwt){
		window.vm.$store.commit('setJwt',{jwt:jwt});
	}
	return response;
}, function(error) {
	return Promise.reject(error);
});

// //Route request interception
// //http request interceptor
// axios.interceptors.request.use(
// 	config => {
// 		//config.data = JSON.stringify(config.data);
// 		//config.headers['Content-Type'] = 'application/json;charset=UTF-8';
// 		//config.headers['Token'] = 'abcxyz';
// 		//Judge whether there is a ticket. If so, add a ticket to each http header
// 		// if (cookie.get("token")) {
// 		//  	// The user sets the cookie to 2 hours for each operation
// 		// 	cookie.set("token", cookie.get("token"), 1 / 12)
// 		// 	cookie.set("name", cookie.get("name"), 1 / 12)
// 		// 	config.headers.token = cookie.get("token");
// 		// 	config.headers.name = cookie.get("name");
// 		// }
// 		return config;
// 	},
// 	error => {
// 		return Promise.reject(error.response);
// 	});

// //Route response interception
// //http response interceptor
// axios.interceptors.response.use(
// 	response => {
// 		if (response.data.resultCode == "404") {
// 			console.log("response.data.resultCode is 404")
// 			//Return error code - 1, clear the ticket information and jump to the login page
// 			//      cookie.del("ticket")
// 			//      window.location.href='http://login.com'
// 			return
// 		} else {
// 			return response;
// 		}
// 	},
// 	error => {
// 		return Promise.reject(error.response) / / returns the error information returned by the interface
// 	});



export default axios;

Write to the front-end variables.js:

setJwt: (state, payload) => {
    state.Jwt = payload.Jwt;
  },

Put the value of jwt token into vuex:

Set the value through changes.js and write the setJwt method:

This keyword can only appear in vue components. In js, the function of vuex to be called window.vm(vm can take it at will) represents this

Mutations.js:

// Variable modification
export default {
  setResturantName: (state, payload) => { //payload: load: actually, it is a container for saving parameters to be transferred, which is an object
    state.resturantName = payload.resturantName;
  },
  setJwt: (state, payload) => {
    state.Jwt = payload.Jwt;
  },
  doAjax:(state,payload)=>{
    //Requirements: you want to interact with the background server in the current file
    let _this = payload._this;
    let url = _this.axios.urls.SYSTEM_MENU_TREE;
    _this.axios.post(url, {}).then((resp) =>{
      console.log(resp);
      _this.menus = resp.data.result;
    }).catch(function(error) {
      console.log(error);
    });

  }
}

State.js defines jwt variables:

/* Variable definition */
export default{
      resturantName:'LongQin Bay'
      jwt:''
}

Getters.js defines the getjwt acquisition method:

export default{
      getResturantName:(state)=>{
        return state.resturantName;
      },
      getJwt:(state)=>{
        return state.Jwt;
      }
}

main.js:

window.vm = new Vue({//At this point, window.vm represents the root instance of Vue
// The Vue build version to load with the `import` command
// (runtime-only or standalone) has been set in webpack.base.conf with an alias.
import Vue from 'vue'
// process.env.MOCK && require('@/mock')
import 'element-ui/lib/theme-chalk/index.css' //  New addition   two  
import App from './App'
import router from './router'
import ElementUI from 'element-ui' //  New addition   one
import axios from '@/api/http'  //#Global configuration of axios by vue project
// import axios from 'axios'     
import VueAxios from 'vue-axios'
import store from './store'

Vue.use(ElementUI)   //  New addition   three
Vue.use(VueAxios,axios)
Vue.config.productionTip = false

/* eslint-disable no-new */
window.vm = new Vue({//At this point, window.vm represents the root instance of Vue
  el: '#app',
  data(){
    return {
      Bus:new Vue({
      /*There's no need to write here  */
      })

    }
  },
  router,
  store,
  components: { App },
  template: '<App/>'
})

Bring the value of jwt into the request header when requesting

Release the http.js request Interceptor:

// request interceptor 
axios.interceptors.request.use(function(config) {
	var jwt = window.vm.$store.getters.getJwt;
	config.headers['jwt'] = jwt;
	return config;
}, function(error) {
	return Promise.reject(error);
});

Bring the value of jwt into the request header the second time

Release the http.js request Interceptor:

// request interceptor 
axios.interceptors.request.use(function(config) {
    var jwt = window.vm.$store.getters.getJwt;
    config.headers['jwt'] = jwt;
    return config;
}, function(error) {
    return Promise.reject(error);
});

Get method defined in Getters.js

export default{
      getResturantName:(state)=>{
        return state.resturantName;
      },
      getJwt:(state)=>{
        return state.Jwt;
      }
}

Question:

In a browser, after logging in to the home page,

Open an interface again, copy the home page link, open the home page, and you can't access the home page,

reason:

The first time there is no jwt in the request header, then the request background server generates a jwt and returns it. At this time, there is a jwt in the response header,

There is jwt in the second access request header, which is used for the second time by taking the first response header. After returning, it is brought back when requesting. Each request is the last one,

When a new interface is opened, there is no jwt in the request header, so it cannot be accessed; The requests in the two request headers are different

Therefore, jwt is more secure than session

2, jwt tool class introduction, three scenarios

1. jwt tool class

The jwt token contains:

Payload: user information

Signature: it's the codebook

 

jwtUtils:

parseJwt method: parse the unreadable string into user information;

createJwt method: change the user information into an incomprehensible string;

package com.zking.vue.util;
 
import java.util.Date;
import java.util.Map;
import java.util.UUID;
 
import javax.crypto.SecretKey;
import javax.crypto.spec.SecretKeySpec;
 
import org.apache.commons.codec.binary.Base64;
 
import io.jsonwebtoken.Claims;
import io.jsonwebtoken.JwtBuilder;
import io.jsonwebtoken.Jwts;
import io.jsonwebtoken.SignatureAlgorithm;
 
/**
 * JWT Validation filter: configuration order corsfilte - > jwtutilsr -- > strutsprepareandexecutefilter
 *
 */
public class JwtUtils {
	/**
	 * JWT_WEB_TTL: WEBAPP The effective time of the token in the application, which is 30 minutes by default
	 */
	public static final long JWT_WEB_TTL = 30 * 60 * 1000;
 
	/**
	 * Save the jwt token to the key in the header
	 */
	public static final String JWT_HEADER_KEY = "jwt";
 
	// The signature algorithm used when specifying the signature, that is, the header part, jjwt has encapsulated this part.
	private static final SignatureAlgorithm SIGNATURE_ALGORITHM = SignatureAlgorithm.HS256;
	private static final String JWT_SECRET = "f356cdce935c42328ad2001d7e9552a3";// JWT key
	private static final SecretKey JWT_KEY;// Encryption key generated using JWT key
 
	static {
		byte[] encodedKey = Base64.decodeBase64(JWT_SECRET);
		JWT_KEY = new SecretKeySpec(encodedKey, 0, encodedKey.length, "AES");
	}
 
	private JwtUtils() {
	}
 
	/**
	 * Decrypt jwt to get all declarations (including standard and private declarations)
	 * 
	 * @param jwt
	 * @return
	 * @throws Exception
	 */
	public static Claims parseJwt(String jwt) {
		Claims claims = Jwts.parser().setSigningKey(JWT_KEY).parseClaimsJws(jwt).getBody();
		return claims;
	}
 
	/**
	 * Create a JWT token, and the issuing time is the current time
	 * 
	 * @param claims
	 *            Create a payload private statement (add it according to specific business needs. If you want to use this for verification, you generally need to communicate the verification method with the jwt receiver in advance)
	 * @param ttlMillis
	 *            JWT The effective time (in milliseconds), current time + effective time = expiration time
	 * @return jwt token
	 */
	public static String createJwt(Map<String, Object> claims, long ttlMillis) {
		// The time when the JWT was generated, that is, the issuing time
		long nowMillis = System.currentTimeMillis();
 
		// The following is to add various standard declarations and private declarations for payload
		// This is actually a new JwtBuilder to set jwt's body
		JwtBuilder builder = Jwts.builder()
				// If there is a private declaration, you must first set the private declaration created by yourself. This is to assign a value to the builder's claim. Once it is written after the assignment of the standard declaration, it overwrites those standard declarations
				.setClaims(claims)
				// Set jti(JWT ID): it is the unique ID of JWT. According to business needs, this can be set as a non duplicate value, which is mainly used as a one-time token to avoid replay attacks.
				// It can be used as an ID before logging in
				.setId(UUID.randomUUID().toString().replace("-", ""))
				// ISS (issuer), write dead
				// .setIssuer("zking")
				// IAT: issuing time of JWT
				.setIssuedAt(new Date(nowMillis))
				// Represents the main body of the JWT, that is, its owner. This is a json format string that can put data {"uid":"zs"}. Not here
				// .setSubject("{}")
				// Set the signature algorithm and secret key used for signature
				.signWith(SIGNATURE_ALGORITHM, JWT_KEY)
				// Set JWT expiration time
				.setExpiration(new Date(nowMillis + ttlMillis));
 
		return builder.compact();
	}
 
	/**
	 * Copy jwt and reset the issue time (current time) and expiration time
	 * 
	 * @param jwt
	 *            jwt token copied
	 * @param ttlMillis
	 *            jwt The effective time (in milliseconds), current time + effective time = expiration time
	 * @return
	 */
	public static String copyJwt(String jwt, Long ttlMillis) {
		Claims claims = parseJwt(jwt);
 
		// The time when the JWT was generated, that is, the issuing time
		long nowMillis = System.currentTimeMillis();
 
		// The following is to add various standard declarations and private declarations for payload
		// This is actually a new JwtBuilder to set jwt's body
		JwtBuilder builder = Jwts.builder()
				// If there is a private declaration, you must first set the private declaration created by yourself. This is to assign a value to the builder's claim. Once it is written after the assignment of the standard declaration, it overwrites those standard declarations
				.setClaims(claims)
				// Set jti(JWT ID): it is the unique ID of JWT. According to business needs, this can be set as a non duplicate value, which is mainly used as a one-time token to avoid replay attacks.
				// It can be used as an ID before logging in
				//.setId(UUID.randomUUID().toString().replace("-", ""))
				// ISS (issuer), write dead
				// .setIssuer("zking")
				// IAT: issuing time of JWT
				.setIssuedAt(new Date(nowMillis))
				// Represents the main body of the JWT, that is, its owner. This is a json format string that can put data {"uid":"zs"}. Not here
				// .setSubject("{}")
				// Set the signature algorithm and secret key used for signature
				.signWith(SIGNATURE_ALGORITHM, JWT_KEY)
				// Set JWT expiration time
				.setExpiration(new Date(nowMillis + ttlMillis));
		return builder.compact();
	}
}

Three scenarios:

jwtDemo:

package com.zking.vue.test;

import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;

import org.junit.Test;

import com.zking.vue.util.JwtUtils;

import io.jsonwebtoken.Claims;

public class JwtDemo {

	private SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.SSS");

	@Test
	public void test1() {// Generate JWT
		Map<String, Object> claims = new HashMap<String, Object>();
		claims.put("username", "zss");
		claims.put("age", 18);

		String jwt = JwtUtils.createJwt(claims, JwtUtils.JWT_WEB_TTL);
		System.out.println(jwt);

		Claims parseJwt = JwtUtils.parseJwt(jwt);
		for (Map.Entry<String, Object> entry : parseJwt.entrySet()) {
			System.out.println(entry.getKey() + "=" + entry.getValue());
		}
		Date d1 = parseJwt.getIssuedAt();
		Date d2 = parseJwt.getExpiration();
		System.out.println("Token issuing time:" + sdf.format(d1));
		System.out.println("Token expiration time:" + sdf.format(d2));
	}

	@Test
	public void test2() {// Parse oldJwt
//		String oldJwt = "eyJhbGciOiJIUzI1NiJ9.eyJleHAiOjE1NjI5MDMzNjAsImlhdCI6MTU2MjkwMTU2MCwiYWdlIjoxOCwianRpIjoiZDVjMzE4Njg0MDcyNDgyZDg1MDE5ODVmMDY3OGQ4NjkiLCJ1c2VybmFtZSI6InpzcyJ9.XDDDRRq5jYq5EdEBHtPm7GcuBz4S0VhDTS1amRCdf48";
		String oldJwt = "eyJhbGciOiJIUzI1NiJ9.eyJleHAiOjE1NjM1MjU5MjMsImlhdCI6MTU2MzUyNDEyMywiYWdlIjoxOCwianRpIjoiOTAzNmMwY2Q3NGIwNDBjMzgzMDAxYzdiNmZkMzYzZmIiLCJ1c2VybmFtZSI6InpzcyJ9.sgV9fr4fgmmahDFRJnsfazA6R3H-gNMVcg2ucA227n4";
		Claims parseJwt = JwtUtils.parseJwt(oldJwt);
		for (Map.Entry<String, Object> entry : parseJwt.entrySet()) {
			System.out.println(entry.getKey() + "=" + entry.getValue());
		}
		Date d1 = parseJwt.getIssuedAt();
		Date d2 = parseJwt.getExpiration();
		System.out.println("Token issuing time:" + sdf.format(d1));
		System.out.println("Token expiration time:" + sdf.format(d2));
	}

	@Test
	public void test3() {// Copy jwt and delay 30 seconds
		String oldJwt = "eyJhbGciOiJIUzI1NiJ9.eyJleHAiOjE1NjI5MDMzNjAsImlhdCI6MTU2MjkwMTU2MCwiYWdlIjoxOCwianRpIjoiZDVjMzE4Njg0MDcyNDgyZDg1MDE5ODVmMDY3OGQ4NjkiLCJ1c2VybmFtZSI6InpzcyJ9.XDDDRRq5jYq5EdEBHtPm7GcuBz4S0VhDTS1amRCdf48";
		String jwt = JwtUtils.copyJwt(oldJwt, JwtUtils.JWT_WEB_TTL);
		Claims parseJwt = JwtUtils.parseJwt(jwt);
		for (Map.Entry<String, Object> entry : parseJwt.entrySet()) {
			System.out.println(entry.getKey() + "=" + entry.getValue());
		}
		Date d1 = parseJwt.getIssuedAt();
		Date d2 = parseJwt.getExpiration();
		System.out.println("Token issuing time:" + sdf.format(d1));
		System.out.println("Token expiration time:" + sdf.format(d2));
	}

	@Test
	public void test4() {// Test the effective time of JWT
		Map<String, Object> claims = new HashMap<String, Object>();
		claims.put("username", "zss");
		String jwt = JwtUtils.createJwt(claims, 3 * 1000L);
		System.out.println(jwt);
		Claims parseJwt = JwtUtils.parseJwt(jwt);
		Date d1 = parseJwt.getIssuedAt();
		Date d2 = parseJwt.getExpiration();
		System.out.println("Token issuing time:" + sdf.format(d1));
		System.out.println("Token expiration time:" + sdf.format(d2));
	}

	@Test
	public void test5() {// Parse the above token with an expiration time of only three seconds after three seconds, because if it expires, an error io.jsonwebtoken.ExpiredJwtException will be reported
		String oldJwt = "eyJhbGciOiJIUzI1NiJ9.eyJleHAiOjE1NjI4NTMzMzAsImlhdCI6MTU2Mjg1MzMyNywidXNlcm5hbWUiOiJ6c3MifQ.e098Vj9KBlZfC12QSDhI5lUGRLbNwb27lrYYSL6JwrQ";
		Claims parseJwt = JwtUtils.parseJwt(oldJwt);
		// After expiration, the parsing will report an error, and the following code will not be executed at all
		Date d1 = parseJwt.getIssuedAt();
		Date d2 = parseJwt.getExpiration();
		System.out.println("Token issuing time:" + sdf.format(d1));
		System.out.println("Token expiration time:" + sdf.format(d2));
	}
}

Result display of three scenarios

The first one is how to generate and parse jwt tokens through jwt tool classes

Second: jwt token expiration scenario

 

The third: the lifetime of the continuation token

The token expiration time is 30 minutes. If it has been in use, it will expire after 30 minutes and log in again. This is unreasonable

Therefore, it is necessary to set the last use time as the issuance time, and the later 30 minutes as the expiration time,

Solution: copy jwt token and reset the issue expiration time

The instruction is a new jwt instruction in the operation of the first method. It should be replaced. Otherwise, an error will be reported and the instruction expires

Well, vue's study is over!

 

Posted by Cliftron on Thu, 02 Dec 2021 12:47:12 -0800