会话跟踪技术

一、会话跟踪

1 什么是会话什么是请求?

会话:浏览器与服务器之间的一次连接
请求:前端发送的指令
@RestController
public class LoginController {
​
    @Autowired
    private EmpService empService;
​
    @PostMapping("/login")
    public ResultData login(@RequestBody Emp emp){
        Emp e = empService.getByUsernameByPassword(emp.getUsername(),emp.getPassword());
        return e != null ? ResultData.success(e) : ResultData.error();
    }
​
}

2 什么是会话跟踪技术?

使用会话跟踪技术就是要完成在同一个会话中,多个请求之间进行共享数据。

3 会话跟踪技术包括?

Cookie(浏览器) ,Session(服务器), 令牌(JWT)

① Cookie

I cookie执行流程:

image-20240709102406330

II Cookie 快速入门:
a. 设置cookie。有响应对象操作

传递参数 HttpServletResponse

设置cookie, 传一个键值对

设置最大存货时间

添加cookie

带到客户端

    // 设置cookie
    @GetMapping("/setc")
    public ResultData setc(HttpServletResponse response){
        //  设置cookie, 传一个键值对
        Cookie cookie = new Cookie("username","lss");
        //  设置最大存货时间 单位为秒
        cookie.setMaxAge(3600);
        //  添加cookie
        response.addCookie(cookie);
        return ResultData.success();
    }
II 获取cookie

传递参数:HttpServletResponse,HttpSession

删除原有session -- session.invalidate();

获取当前服务器中所有存在的自己的cookie

合理化校验

遍历判断要获取的cookie存不存在 用key去判断

// 获取cookie
    @GetMapping("/getc")
    public ResultData getc(HttpServletRequest request, HttpSession session){
        // 删除原有session
        session.invalidate();
        Cookie[] cookies = request.getCookies();
        if (cookies != null && cookies.length > 0){
            for (Cookie cookie : cookies) {
                if ("username".equals(cookie.getName())){
                    System.out.println(cookie.getValue());
                }
            }
        }
        return ResultData.success();
    }

③ Session(服务器端会话跟踪技术):

1 服务器创建(服务器中有session池)执行流程:

image-20240709105620501

2 Session快速入门
I 设置session

传递参数 HttpSession

放数据

返回去

    // 设置session
    @GetMapping("/sets")
    public ResultData sets(HttpSession session){
        session.setAttribute("username","张三");
        return ResultData.success();
    }
II 获取Session

传递参数 HttpServletRequest

获得session

存放对象(要强转)

返回去

    // 获取session
    @GetMapping("/gets")
    public ResultData gets(HttpServletRequest request){
        HttpSession session = request.getSession();
        String username = (String) session.getAttribute("username");
        return ResultData.success(username);
    }

④ 令牌技术

1 jwt 令牌技术
简介:一个简洁的、 自包含的格式
组成:(JWT令牌由三个部分组成,三个部分之间使用英文的点来分割)
  • 第一部分:Header(头), 记录令牌类型、签名算法等。 例如:{"alg":"HS256","type":"JWT"}

  • 第二部分:Payload(有效载荷),携带一些自定义信息、默认信息等。 例如:{"id":"1","username":"Tom"}

  • 第三部分:Signature(签名),防止Token被篡改、确保安全性。将header、payload,并加入指定秘钥,通过指定签名算法计算而来。

2 jwt 使用:

I 引入依赖
<!-- JWT依赖-->
<dependency>
    <groupId>io.jsonwebtoken</groupId>
    <artifactId>jjwt</artifactId>
    <version>0.9.1</version>
</dependency>
II 创建jwt

jwt是个接口,实体类过于复杂,使用工厂设计模式(工具类带s的)

创建map,添加jwt要传的内容 -- 载体对象(Claims)

生成jwt:声明 jwt 添加荷载部分,添加头部信息 算法和密钥, 添加有效期,最后构建密钥

@Test
    public void CreateJWT(){
        JwtBuilder builder = Jwts.builder();
        Map<String,Object> claims = new HashMap<>();
        claims.put("id",1);
        claims.put("username","tom");
        String jwt = builder.addClaims(claims)
                .signWith(SignatureAlgorithm.HS256, "wolfcode")
                .setExpiration(new Date(System.currentTimeMillis() + 1000 * 60 * 3))
                .compact();
        System.out.println(jwt);
    }
III 解析令牌:

指定密钥

提供一大堆jwt

    @Test
    public void parseJwt(){
        JwtParser jwt = Jwts.parser().setSigningKey("wolfcode");
        Claims claims = jwt.parseClaimsJws("eyJhbGciOiJIUzI1NiJ9.eyJpZCI6MSwidXNlcm5hbWUiOiJ0b20iLCJleHAiOjE3MjA1MjU0MjF9.AhuZUWrm5IwMioERz5FHw4fgXnfq_hnOcK89pI-4L0g").getBody();
        System.out.println(claims);
    }
IV 封装工具类

封装字段:

签名密钥

有效时间

    private String signingKey;
    private String expiration;

封装方法:

生成JWT令牌

    public static String createJwt(Map<String,Object> claims){
        JwtBuilder builder = Jwts.builder();
        String jwt = builder.addClaims(claims)
                .signWith(SignatureAlgorithm.HS256, signingKey)
                .setExpiration(new Date(System.currentTimeMillis() + expiration))
                .compact();
        return jwt;
    }

解析JWT令牌

    public static Claims parseJwt(String claims){
        Claims jwt = Jwts.parser()
                .setSigningKey(signingKey)
                .parseClaimsJws(claims)
                .getBody();
        return jwt;
    }
V 更改控制层

判断登录是否成功

若失败返回错位信息

定义载体信息,把查到的值传进去

调用工具类生成令牌,将map塞进去

返回数据

  @PostMapping("/login")
    public ResultData login(@RequestBody Emp emp){
        Emp e = empService.getByUsernameByPassword(emp.getUsername(),emp.getPassword());
        if (e == null){
            return ResultData.error("用户名失败");
        }
        Map<String, Object> claims = new HashMap<>();
        claims.put("id",1);
        claims.put("username","张三");
        String jwt = JWTUtils.createJwt(claims);
        return ResultData.success(jwt);
    }
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值