会话跟踪令牌技术

目录

会话跟踪

Cookis

Session

令牌技术

JWT令牌技术

用途

组成

解析数据

JWT是如何将原始的JSON格式数据,转变为字符串的呢?

令牌实现操作案例

登录下发令牌

实现步骤

1.引入JWT工具类

2.登录完成后,调用工具类生成JWT令牌并返回


会话跟踪

Cookis

优点

Http协议支持的技术

缺点

移动端app无法使用

不安全

不能跨域

Session

优点

存储在服务端,安全

缺点

服务器集群环境下无法直接使用Session

还有Cookie的缺点

令牌技术

优点

支持PC端,移动端

解决集群环境下的认证问题

减轻服务器存储的压力

缺点

需要自己实现

JWT令牌技术

简洁

指jwt就是一个简单的字符串。可以在请求参数或者是请求头当中直接传递。

自包含

指的是jwt令牌,看似是一个随机的字符串,但是我们是可以根据自身的需求在jwt令牌中存储自定义的数据内容。如:可以直接在jwt令牌中存储用户的相关信息。

用途

在通信双方以json数据格式安全的传输信息,所以安全

组成

由三个部分之间使用点来分割

Header(头):记录令牌类型、签名算法等

Payload(有效载荷):携带一些自定义信息、默认信息

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

解析数据

JWT是如何将原始的JSON格式数据,转变为字符串的呢?

在生成JWT令牌时,会对JSON格式的数据进行一次编码:进行base64编码

一种基于64个可打印的字符来表示二进制数据的编码方式

64个字符分别是A到Z、a到z、 0- 9,一个加号,一个斜杠,加起来就是64个字符还有一个符号,等号它是一个补位的符号

是编码方式,而不是加密方式

令牌实现操作案例

1. 在登录成功之后,要生成令牌。

先引入JWT的依赖

<!-- JWT依赖-->
<dependency>
    <groupId>io.jsonwebtoken</groupId>
    <artifactId>jjwt</artifactId>
    <version>0.9.1</version>
</dependency>

生成JWT代码

@Test
public void genJwt(){
    Map<String,Object> claims = new HashMap<>();
    claims.put("id",1);
    claims.put("username","Tom");
    
    String jwt = Jwts.builder()
        .setClaims(claims)      //自定义内容(载荷)          
        .signWith(SignatureAlgorithm.HS256, "itheima") //签名算法        
        .setExpiration(new Date(System.currentTimeMillis() + 24*3600*1000)) //有效期   
        .compact();
    
    System.out.println(jwt);
}

2. 每一次请求当中,要接收令牌并对令牌进行校验。

可以校验JWT令牌(解析生成的令牌):

@Test
public void parseJwt(){
    Claims claims = Jwts.parser()
        .setSigningKey("itheima")//指定签名密钥(必须保证和生成令牌时使用相同的签名密钥)  
        .parseClaimsJws("eyJhbGciOiJIUzI1NiJ9.eyJpZCI6MSwiZXhwIjoxNjcyNzI5NzMwfQ.fHi0Ub8npbyt71UqLXDdLyipptLgxBUg_mSuGJtXtBk")
        .getBody();

    System.out.println(claims);
}

使用JWT令牌时需要注意

JWT校验时使用的签名秘钥,必须和生成JWT令牌时使用的秘钥是配套的。

如果JWT令牌解析校验时报错,则说明 JWT令牌被篡改 或 失效了,令牌非法。 

登录下发令牌

实现步骤

1.引入JWT工具类

public class JwtUtils {

    private static String signKey = "itheima";//签名密钥
    private static Long expire = 43200000L; //有效时间

    /**
     * 生成JWT令牌
     * @param claims JWT第二部分负载 payload 中存储的内容
     * @return
     */
    public static String generateJwt(Map<String, Object> claims){
        String jwt = Jwts.builder()
                .addClaims(claims)//自定义信息(有效载荷)
                .signWith(SignatureAlgorithm.HS256, signKey)//签名算法(头部)
                .setExpiration(new Date(System.currentTimeMillis() + expire))//过期时间
                .compact();
        return jwt;
    }

    /**
     * 解析JWT令牌
     * @param jwt JWT令牌
     * @return JWT第二部分负载 payload 中存储的内容
     */
    public static Claims parseJWT(String jwt){
        Claims claims = Jwts.parser()
                .setSigningKey(signKey)//指定签名密钥
                .parseClaimsJws(jwt)//指定令牌Token
                .getBody();
        return claims;
    }
}

2.登录完成后,调用工具类生成JWT令牌并返回

@RestController
@Slf4j
public class LoginController {
    //依赖业务层对象
    @Autowired
    private EmpService empService;

    @PostMapping("/login")
    public Result login(@RequestBody Emp emp) {
        //调用业务层:登录功能
        Emp loginEmp = empService.login(emp);

        //判断:登录用户是否存在
        if(loginEmp !=null ){
            //自定义信息
            Map<String , Object> claims = new HashMap<>();
            claims.put("id", loginEmp.getId());
            claims.put("username",loginEmp.getUsername());
            claims.put("name",loginEmp.getName());

            //使用JWT工具类,生成身份令牌
            String token = JwtUtils.generateJwt(claims);
            return Result.success(token);
        }
        return Result.error("用户名或密码错误");
    }
}

点击这里查看更多知识

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值