Token's web session tracking technology

Token-based web session tracking development process

In the process of front-end and back-end interaction, the back-end needs to know which user is operating on the front-end, and the http request is stateless, and it is a request-response mode, and there is no identity identification in the request message. This requires the use of other means to identify the user's information, and this means is token.

Basic flow of session tracking

1. During the front-end login operation, send account information to the back-end, and generate a token string after receiving the account information at the back-end

The way to generate token here is by importing the jar package of jwt, and then using related methods to generate the implementation code as follows:

public class JWTUtil {
    /**
     * jwt 生成 token
     * @param id
     * @param account * @return
     */
    public static String token (Integer id, String account){
        String token = "";
        try {
             //过期时间 为 1970.1.1 0:0:0 至 过期时间 当前的毫秒值 + 有效时间
            Date expireDate = new Date(new Date().getTime() +60*60*24*1000);
             //秘钥及加密算法  加盐
            Algorithm algorithm = Algorithm.HMAC256("ZCEQIUBFKSJBFJH2020BQWE");
           //设置头部信息
            Map<String,Object> header = new HashMap<>();
            header.put("typ","JWT");//生成类型
            header.put("alg","HS256");//加密算法
            //携带 id,账号信息,生成签名
            token = JWT.create()
                    .withHeader(header)
                    .withClaim("id",id)//用户id
                    .withClaim("account",account)//用户账号
                    .withExpiresAt(expireDate)//过期时间
                    .sign(algorithm);
        }catch (Exception e){
            e.printStackTrace(); return null;
        }
        return token;
    }
    public static boolean verify(String token){
        try {
         //验签
            Algorithm algorithm = Algorithm.HMAC256("ZCEQIUBFKSJBFJH2020BQWE");
            JWTVerifier verifier = JWT.require(algorithm).build();
            DecodedJWT jwt = verifier.verify(token);
            return true;
        } catch (Exception e) {//当传过来的 token 如果有问题,抛出异常
            return false;
        }
    }
    /**
     * 获得 token 中 playload 部分数据,按需使用
     * @param token
     * @return
     */
    public static DecodedJWT getTokenInfo(String token){
        return JWT.require(Algorithm.HMAC256("ZCEQIUBFKSJBFJH2020BQWE")).build().verify(token);
    }
}

To generate tokens in business only need

String token = JWTUtil.token(admin.getId(),admin.getAccount());

This piece of code will do

2. Encapsulate the token into the response information and send it to the front end

3. The front end receives and stores the token in the sessionStorage object of the browser

sessionStorage.setItem("token",data.data.token);

4. Put the token into the request header and send it to the backend for verification every time a request is sent later

Here you can write this piece of business code into the request interceptor, so you don’t have to add it separately every time you send a request

Add this code to main.js

axios.interceptors.request.use(config =>{ ​ //For the request header object, add the token field for Token verification config.headers.token = window.sessionStorage.getItem('token'); ​ return config; ​ } )

5. Receive front-end information and verify it at the back end

Since token verification is required during each front-end and back-end interaction, in order to reduce code redundancy, filters can be used to help us complete this work. The code implementation is as follows:

public class TokenFilter implements Filter {
    @Override
    public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
        HttpServletRequest req = (HttpServletRequest)servletRequest;
        String token = req.getHeader("token");
        boolean res = JWTUtil.verify(token);
        if (res){
            filterChain.doFilter(servletRequest,servletResponse);
        }else{
            HttpServletResponse resp = (HttpServletResponse)servletResponse;
            resp.setContentType("text/html;charset=utf-8");
            CommandResult commandResult = new CommandResult(202,null,"验证token失败");
            PrintWriter printWriter= resp.getWriter();
            printWriter.print(new ObjectMapper().writeValueAsString(commandResult));
        }
    }
}

If a forged token is found or the time of the token expires, the token verification will fail, and a code value can be returned to the front end according to the business

Get the information in the token:

String token = req.getHeader("token");

DecodedJWT dec = JWTUtil.getTokenInfo(token);

int id = dec.getClaim("id").asInt();//Get the id in the token

String account = dec.getClaim("account").asString();//Get the account information in the token

6. Add a response interceptor to the front end

If the token verification fails, the backend sends an ID back to the frontend to tell the frontend that the token verification failed

However, in such frequent front-end and back-end interactions, if each piece of business code judges whether the token is successfully verified, it will lead to a lot of code redundancy.

The best way is to add a response interceptor to manage the information that the backend responds to the frontend

Add the following code in main.js

axios.interceptors.response.use((resp) =>{//Normal response interception

        if(resp.data.code==500){ ElementUI.Message({message:resp.data.message,type:"error"}) }

        if(resp.data.code==202){//The flag set here is 202

        sessionStorage.clear();//Clear after authentication failure

        Account and token information in the sessionStorage object

        router.replace("/login");//Return to the login interface }

return resp; });

Guess you like

Origin blog.csdn.net/yzl1293346757/article/details/127787131