Talking about Session and Token


foreword

The HTTP protocol itself is a stateless protocol

Stateless: For multiple requests from the same client, the server cannot identify the identity of the client. For example, when receiving the client's request for the second time, it does not know that the client has submitted a request before, let alone the second request. 1 data generated when processing this client request

In development practice, it is necessary to clarify the identity of the client. Therefore, from a technical perspective, Session and Token can be used to solve the stateless problem of the HTTP protocol.


1. What is Session?

1 Introduction

Session: session

The essence of a session is data in a MAP structure. When the client submits a request to the server for the first time, the server will respond with a Session ID to the client. In subsequent visits, the client will automatically carry the Session ID in the request, and at the same time , there will be session data corresponding to each Session ID in the memory of the server, so that each client can access its own previously stored data

Since the Session is the data in the server-side memory, it is not suitable for the cluster system by default, let alone the distributed system

2. How to use

The following will be substituted into the actual business to demonstrate how to use it:

a. In the business of processing user login requests, when the login is verified successfully, the setAttribute() method of the Session object is called to save the successfully logged-in user object into the session object

@RequestMapping("/login")
    public int login(@RequestBody User user, HttpSession session, HttpServletResponse response){
        System.out.println("user = " + user);
        User u = mapper.selectByUsername(user.getUsername());
        if(u!=null){
            if(u.getPassword().equals(user.getPassword())){
                //把登录成功的用户对象保存到会话对象里面
                session.setAttribute("user",u);
                
                return 1;
            }
            return 2;
        }
        return 3;
    }

b. Call the getAttribute() method of the Session object to take out the session object

@RequestMapping("/currentUser")
    public User currentUser(HttpSession session){
        //取出会话对象中 登录成功时保存进去的用户对象
        User user = (User)session.getAttribute("user");
        System.out.println("user = " + user);
        return user;
    }

c. When the client logs out, call the removeAttribute() method of the Session object to delete the session object

@RequestMapping("/logout")
    public void logout(HttpSession session){
        //删除会话对象中的user
        session.removeAttribute("user");
    }

2. What is Token?

1 Introduction

Token: ticket, token

When the user tries to log in, submit the request to the server. If the server-side authentication passes, it will generate a Token data and respond to the client. This Token is meaningful data. The client should send it to each subsequent request. Carrying this Token data, the server identifies the user by parsing the Token

 

 
 

2. How to use

JWT: JSON Web Token: A Token that uses JSON format to represent multiple data

Before using JWT, you need to add relevant dependencies to the project for generating JWT and parsing JWT. You can refer to the official website: jwt.io

For example:

<!-- JJWT(Java JWT) -->
<dependency>
    <groupId>io.jsonwebtoken</groupId>
    <artifactId>jjwt</artifactId>
    <version>0.9.1</version>
</dependency>

A raw JWT data should contain:

HEADER: ALGORITHM & TOKEN TYPE (algorithm and Token type)

PAYLOAD (load): DATA

VERIFY SIGNATURE (verify signature)

The following will show you how to use it in the test class:

public class JwtTests {

    // Secret Key
    String secretKey = "97iuFDVDfv97iuk534Tht3KJR89kBGFSBgfds";

    @Test
    public void testGenerate() {//生成JWT
        // 准备Claims值
        Map<String, Object> claims = new HashMap<>();
        claims.put("id", 9527);
        claims.put("name", "liudehua");
        claims.put("nickname", "andy");

        // JWT的过期时间
        Date expiration = new Date(System.currentTimeMillis() + 5 * 60 * 1000);  
        //五分钟后过期
        System.out.println("过期时间:" + expiration);


        // JWT的组成:Header(头:算法和Token类型)、Payload(载荷)、Signature(签名)
        String jwt = Jwts.builder()
                // Header
                .setHeaderParam("alg", "HS256")
                .setHeaderParam("typ", "JWT")
                // Payload
                .setClaims(claims)
                .setExpiration(expiration)
                // Signature
                .signWith(SignatureAlgorithm.HS256, secretKey)
                .compact();
        System.out.println("JWT=" + jwt);

        /*eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJuYW1lIjoibGl1ZGVodWEiLCJuaW
        NrbmFtZSI6ImFuZHkiLCJpZCI6OTUyNywiZXhwIjoxNjYyNDYzMzcyfQ.GW6aDBTc5ZZh
        PbsaqPeP3MNaMN2e6jjlzX_VZdqtwR8*/
    }


    @Test
    public void testParse() {//解析JWT
        // 注意:必须使用相同secretKey生成的JWT,否则会解析失败
        // 注意:不可以使用过期的JWT,否则会解析失败
        // 注意: 使用过期的JWT,也会解析失败
        // 注意:复制粘贴此JWT时,不要带“尾巴”,否则会解析失败
        // 注意:不可以恶意修改JWT中的任何字符,否则会解析失败
        String jwt = "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJuYW1lIjoibGl1ZGVodW" +
                "EiLCJuaWNrbmFtZSI6ImFuZHkiLCJpZCI6OTUyNywiZXhwIjoxNjYyNDYzMzcyfQ" +
                ".GW6aDBTc5ZZhPbsaqPeP3MNaMN2e6jjlzX_VZdqtwR8";
        Claims claims = Jwts.parser()
                .setSigningKey(secretKey)
                .parseClaimsJws(jwt)
                .getBody();
        Integer id = claims.get("id", Integer.class);
        String name = claims.get("name", String.class);
        String nickname = claims.get("nickname", String.class);
        System.out.println("id = " + id);
        System.out.println("name = " + name);
        System.out.println("nickname = " + nickname);
    }

}

Summarize

About Session and Token: Session is the data stored in the server's memory by default, which will occupy certain server memory resources, and is not suitable for clusters or distributed systems (although it can be solved by sharing the Session). The Session ID carried by the client is only It has unique characteristics (theoretically) and does not have data meaning... and the essence of Token is the result of encrypting meaningful data. Each server only needs to have the function of parsing the encrypted data. The meaning of the information that can be obtained theoretically does not occupy memory resources, and is more suitable for clusters and distributed systems. However, there is a certain risk of being decrypted (the probability is extremely low).

Guess you like

Origin blog.csdn.net/weixin_72125569/article/details/126729187