前置学习:
- http
- springmvc
文章目录
- 会话技术
- cookie
- 设置cookie
- 获取cookie
- cookieAPI
- 优缺点
- cookie的删除
 
- session
- 设置session
- 删除session的某个值
- 获取sesssion
- 优缺点
 
- 令牌JWT
- JWT介绍
- JWT的使用
- java-jwt
- jjwt
- 手动解析
 
会话技术
会话:用户打开浏览器,访问web服务器资源,会话建立,直到有一方断开连接会话结束,一次会话可以多次请求和连接
会话跟踪:一种维护浏览器状态的方式,服务器需要识别多次请求是否来自同一浏览器,以便同一次会话多次请求间共享数据。
cookie
cookies就是一种暂存在你浏览器中的一些信息文件
设置cookie
    @GetMapping("/set")
    public String setCookie(HttpServletResponse response) {
        response.addCookie(new Cookie("name","yu"));
        return "cookie";
    }
然后会在响应头中加一个Set-Cookie
 
获取cookie
    @GetMapping("/get")
    public String getCookie(HttpServletRequest request) {
        Cookie[] cookies = request.getCookies();
        Arrays.stream(cookies).forEach(System.out::println);
        return "cookie";
    }
然后会获取到所有的cookie
 
请求头会携带cookie
 
cookieAPI
// 有get和set方法的
// cookie注释
Comment
// cookie的域
// 域名的形式由RFC 2109指定。域名以句点(.foo.com)开头
// 表示cookie对指定域名系统(DNS)区域中的服务器可见(例如,www.foo.com,但不是A.b.foo.com)。
// 默认情况下,cookie只返回给发送它们的服务器。
Domain
// 最长使用期限(以秒为单位)
MaxAge
// 指定cookie的路径,客户端应将cookie返回到该路径
Path
// 是否应仅使用HTTPS或SSL等安全协议发送cookie。
Secure
// cookie的key 和 value
Name value
// 版本
Version
优缺点
优点
- HTTP协议支持的技术
缺点
- 移动端APP不能使用cookie
- 不安全,用户可以禁止cookie
- cookie不能跨域
cookie的删除
设置cookie的maxage为0就可以了
session
Session是另一种记录浏览器状态的机制,Cookie保存在浏览器中,Session保存在服务器中。用户使用浏览器访问服务器的时候,服务把用户的信息,以某种形式记录在服务器,这就是Session
设置session
这里就不是request或者response了
    @GetMapping("/set")
    public String setSession(HttpSession session){
        session.setAttribute("user","1234");
        return "ok";
    }
就会在setcookie响应报文中生成一个jsessionid的cookie,所以说session还是基于cookie的,只是数据在服务器。
 
 设置之后,响应的时候如果检测到有session,则会将这次会话的session发送过去。
删除session的某个值

 可以看到先进行了判断。value为null就会删掉,所以删除session的值的方法就是设置value为null。
 
获取sesssion
    @GetMapping("/get")
    public String getSession(HttpServletRequest request){
        HttpSession session = request.getSession();
        Object sessionAttribute = session.getAttribute("user");
        System.out.println(sessionAttribute);
        return "ok";
    }

如果将sessionid在浏览器进行删除。重新get,发现获取值为null,然后重新设置了一次session。所以如果删掉,服务器应该就找不到你的信息了。
 
 
优缺点
优点
 存储在服务器,安全
缺点
- 集群环境无法使用session
- cookie的缺点
令牌JWT
JWT介绍
JWT全名JSON WEB TOKEN
 也就是将json进行了封装
JWT的组成有3部分
 第一部分:头,记录令牌的类型、签名算法。
 第二部分:自定义信息,
 第三部分:签名、防止被修改。
生成:
 第一部分、第二部分进行base64编码生成的
 第三部分是加入12部分和签名算法以及密钥进行签名。
优点
- 支持pc端、移动端
- 解决集群认证
- 减轻服务器存储
缺点
 1。 需要自己实现
JWT的使用
java的JWT实现有挺多的。这里选取2个星最多的进行学习。
 maven坐标
 可以看到java-jwt是jwt官方的实现
        <dependency>
            <groupId>com.auth0</groupId>
            <artifactId>java-jwt</artifactId>
            <version>4.2.1</version>
        </dependency>
        <dependency>
            <groupId>io.jsonwebtoken</groupId>
            <artifactId>jjwt-root</artifactId>
            <version>0.11.5</version>
        </dependency>

 
java-jwt
生成jwt
还有些设置,这里列举用的多的
        JWT.create()  // 新建jwt构造器
                .withPayload(Map.of("key1","value1")) // 添加要设置为有效载荷的特定索赔。如果所提供的映射为null,则不会更改任何内容
                .withClaim("字符串","类型有很多") // 添加自定义索赔值
                .withArrayClaim("数组",new String[]{"String","Integer","Long3类数组"}) // 添加自定义索赔值
                .withJWTId("jwtid") //将特定的JWTId(“id”)声明添加到有效载荷中。
                .withKeyId("keyid") //将特定的密钥Id(“kid”)声明添加到标头中。
                .withSubject("subject") //将特定的主题(“sub”)声明添加到有效载荷中。
                .withExpiresAt(new Date(System.currentTimeMillis() + 1000*60))  //设置超时时间,60s后过期
                .sign(Algorithm.HMAC256("密钥需要5个字符以上")); // 以指定签名算法生成密钥
验证jwt
        JWT.require(Algorithm.HMAC256("密钥需要5个字符以上")) // 验证的算法
                .build() // 创建验证
                .verify("set的token") // 根据给定的令牌执行验证。
                .getClaims(); // 获取参数
jjwt
生成
        Map<String,Object> claims = new HashMap<>();
        claims.put("key1","value1");
        Jwts.builder()
                .setClaims(claims) // 添加要设置为有效载荷的特定索赔
                .setExpiration(new Date(System.currentTimeMillis() + 1000*60)) //设置超时时间,60s后过期
                .signWith(SignatureAlgorithm.ES256,"密钥")
                .setId()
                .compact() // 生成token
验证,如果报错则被修改。
        Claims body = Jwts.parser()
                .setSigningKey("密钥")
                .parseClaimsJws("set的token")
                .getBody();
手动解析
程序有一个token
 
复制去官网,就可以了,不过不能验证。
 这也说明了,token的数据是不安全的,验证是安全的。
 


















