Login authentication: why use JWT to replace cookie and session technology

Table of contents

1. Understand where the successful login information is stored after user authentication is successful

-> cookie and session technology

2. How to view these user information (account, password and authority)

3. Stateless session analysis

---> cookie session single login

 ----> Small and medium-sized single sign-on design pattern (relatively simple)

 ----> sso single sign-on

4 specific realization

1. jwt(token)jsonwebtoken

Official website: https://jwt.io

2. The test class understands the process of making token and parsing token


1. Understand where the successful login information is stored after user authentication is successful

-> cookie and session technology

Although Cookie and Session are very common web development technologies, they will be gradually eliminated for the following reasons:

  1. Privacy and security issues: Storing sensitive information in cookies may be stolen by hackers, resulting in losses. In addition, the expiration time of cookies is usually long-term, which means that user information may always be stored locally and thus be abused.

  2. Cross-domain issues: If users use the same website under multiple domain names, cookies will encounter obstacles in passing between different domain names, causing problems when users use the website.

  3. Scalability issues: Cookies and Sessions are based on the HTTP protocol. With the development of Web technology, the HTTP protocol can no longer meet some business needs that need to be implemented, such as WebSockets.

Therefore, developers are gradually adopting new technologies to replace Cookie and Session, such as Token and JWT. These new technologies can store user information more securely and overcome some shortcomings of traditional technologies.

2. How to view these user information (account, password and authority)

/**
     * 获取登录用户信息
     * 登录成功会存到哪
     * 如何获取登录信息
     * @return
     */
    @GetMapping("/doGetUser")
    public String doGetUser(){
        Authentication authentication =
                SecurityContextHolder.getContext().getAuthentication();
        User principal = (User)authentication.getPrincipal();
        System.out.println("principal.class="+principal.getClass());
        //.getClass 表示获取获取类型
        return principal.getUsername()+","+principal.getAuthorities();
    }

3. Stateless session analysis

        Three login (session state) design patterns

---> cookie session single login

A single direct cookie+session, small-scale business and old business exist, but it seems a bit tasteless in a distributed system 

 ----> Small and medium-sized single sign-on design pattern (relatively simple)

 

 ----> sso single sign-on

The client records the session state and the server is only responsible for parsing the token 

Simplified diagram of registration center, remote call, log collection, database, etc. not drawn 

4 specific realization

1. jwt(token)jsonwebtoken

Official website:  https://jwt.io

 Three parts JWT usually consists of three parts, namely Header (head), Payload (load), Signature (signature)

xxxxx.yyyyy.zzzzz
eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyfQ.SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5c

 ---------->

2. The test class understands the process of making token and parsing token

package com.cy.jt.security;

import io.jsonwebtoken.Claims;
import io.jsonwebtoken.Jws;
import io.jsonwebtoken.Jwts;
import io.jsonwebtoken.SignatureAlgorithm;
import org.junit.jupiter.api.Test;
import org.springframework.boot.test.context.SpringBootTest;

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

@SpringBootTest
public class JwtTests {
    public static final String JWT_SECRET ="AAABBBCCCDDDDEEE";//加密盐
    //测试创建解析token
    @Test
    void testCreateAndParseToken(){
        //创建token(头信息,负载信息,签名信息)
        //1.1 获取登录认证信息(例如用户名,权限)
        Map<String,Object> map=new HashMap<>();
        map.put("username", "pzy");
        map.put("permissions", "sys:res:create,sys:res:retrieve");
//日历对象 Date方法中的方法已经不再推荐使用了 对日期进行加减运算

        Calendar calendar = Calendar.getInstance();//当前时间
        //在当前时间的基础上加30分钟
        calendar.add(Calendar.MINUTE, 30);
        Date expirationTime = calendar.getTime();//获取30分钟后的时间
        System.out.println("expirationTime:==>"+expirationTime);

//jwts方法创建token
        String token = Jwts.builder()
                .setSubject("jwt")//主题
                .setClaims(map)// 负载信息(登录信息,没有密码)
                //.setExpiration(new Date(System.currentTimeMillis() + 30 * 1000))//过期时间
                .setExpiration(expirationTime)//过期时间
                .setIssuedAt(new Date())//签发时间
                .signWith(SignatureAlgorithm.HS256,JWT_SECRET)//设置签名加密算法和盐
                .compact();//制作token
        System.out.println("token:===>"+token);
        //解析token
//eyJhbGciOiJub25lIn0.eyJwZXJtaXNzaW9ucyI6InN5czpyZXM6Y3JlYXRlLHN5czpyZXM6cmV0cmlldmUiLCJleHAiOjE2MzQ4NzM1MjAsImlhdCI6MTYzNDg3MzQ5MCwidXNlcm5hbWUiOiJqYWNrIn0.

        Claims claims = Jwts.parser()
                .setSigningKey(JWT_SECRET)
                .parseClaimsJws(token) //最爱出错的问题
                .getBody();
        System.out.println("claims: ===> "+claims);


    }
}

In security, cooperate with jwt to realize authentication and login authentication operation, and in oauth2, the operation steps are simplified, the basic parameters are passed in, and @bean is injected.

The password is also changed from background plaintext record to md5 plus salt encryption and is changing to bcrypt encryption

Generally used with interceptors

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.springframework.stereotype.Component;
import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;

@Component
public class AuthInterceptor implements HandlerInterceptor {

    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        String token = request.getHeader("Authorization");

        // 验证token的过程
        if (verifyToken(token)) {
            return true;
        } else {
            response.sendError(HttpServletResponse.SC_UNAUTHORIZED, "Unauthorized");
            return false;
        }
    }

    @Override
    public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
    }

    @Override
    public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception exception) throws Exception {
    }

    private boolean verifyToken(String token) {
        // 进行token的验证
        // 如果验证成功返回true,否则返回false
    }
}
 

Guess you like

Origin blog.csdn.net/pingzhuyan/article/details/120884364