登录校验-JWT令牌
本文最后更新于 89 天前,其中的信息可能已经有所发展或是发生改变。

一、简介/概述:

用户登录成功后,系统会自动下发JWT令牌,然后在后续的每次请求中,浏览器都需要在请求头header中携带到服务端,请求头的名称为 Authorization,值为 登录时下发的JWT令牌。如果检测到用户未登录,则http响应状态码为401

二、优点

  • 承载业务数据,减少后续请求查询数据库的次数
  • 防篡改,保证信息的合法性和有效性

token是令牌的意思,java对Jason数据进行编码(使用Base64进行编码),因为Base64可以编码,也可以解码,所以在payload部分不能存放密码信息

三、JWT令牌的生成和校验(基于java代码)

/**
 * 生成JWT
 */
@Test
public void testGenJwt() {
    Map<String, Object> claims = new HashMap<>();
    claims.put("id", 1);
    claims.put("name", "tom");

    String jwt = Jwts.builder()
           .signWith(SignatureAlgorithm.HS256, "itheima")//签名算法
           .setClaims(claims) //自定义内容(载荷)
           .setExpiration(new Date(System.currentTimeMillis() + 3600 * 1000))//设置有效期为1h
           .compact();
    System.out.println(jwt);
}

代码解析:
.Jwts.builder():这是 JJWT 库中用于构建 JWT 的起始方法,它返回一个JwtBuilder对象,后续可以通过链式调用一系列方法来配置 JWT 的各个属性。
.signWith(SignatureAlgorithm.HS256, “itheima”):指定 JWT 的签名算法为 HS256(HMAC – SHA256),并设置签名密钥为字符串”itheima”。签名用于验证 JWT 的完整性和真实性,防止令牌被篡改。
.setClaims(claims):这里的claims是一个Map类型(通常是HashMap),用于存储自定义的负载信息,比如用户 ID、用户名、权限等。这些信息会被编码到 JWT 的负载部分。
.setExpiration(new Date(System.currentTimeMillis() + 3600 * 1000)):设置 JWT 的过期时间。代码中计算了从当前时间开始往后 1 小时(3600 * 1000毫秒)的时间点作为过期时间。
.compact():该方法将前面配置好的 JWT 构建成一个紧凑的字符串形式,即最终生成的 JWT 令牌,它是由三部分(头部、负载、签名)经过 Base64Url 编码后,用.连接起来的字符串。

/**
解析JWT令牌
**/
@Test
public void parseJwt() {
    Claims claims = Jwts.parser()
           .setSigningKey("itheima") //指定签名秘钥
           .parseClaimsJws("eyJhbGciOiJIUzI1NiJ9.eyJpZCI6MSwiZXhwIjoxNjU1OTk1NTE3LCJ1c2VybmFtZSI6InRvbSJ9.EUTfeqPkGslekdKBezcWCe7a7xbcllwB1MXllccTMwo") //解析令牌
           .getBody();
    System.out.println(claims);
}

代码解析

.Jwts.parser():这是 JJWT 库中用于开始解析 JWT 的方法,返回一个JwtParser对象。

.setSigningKey("itheima"):设置用于验证 JWT 签名的密钥为"itheima"。在生成 JWT 时会使用一个密钥进行签名,解析时必须使用相同的密钥才能成功验证。

.parseClaimsJws("eyJhbGciOiJIUzI1NiJ9.eyJpZCI6MSwiZXhwIjoxNjU1OTk1NTE3LCJ1c2VybmFtZSI6InRvbSJ9.EUTfeqPkGslekdKBezcWCe7a7xbcllwB1MXllccTMwo"):尝试解析给定的 JWT 字符串。这里的 JWT 字符串由三部分组成,分别是头部、负载和签名,以.分隔。如果签名验证通过,该方法会返回一个包含 JWT 信息的Jws<Claims>对象。

.getBody():从Jws<Claims>对象中获取 JWT 的负载部分,负载中包含了自定义的用户信息等内容,这里将其赋值给claims变量,claims是一个Claims类型的对象,本质上是一个Map<String, Object>,可以通过键来获取对应的值。

四、思路

– 令牌生成:登录成功后,生成JWT令牌,并返回给前端。

– 令牌校验:在请求到达服务端后,对令牌进行统一拦截、校验。

五、实战

– 引入JWT令牌操作工具类。

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

@Autowired
private EmpService empService;

@PostMapping("/login")
public Result login(@RequestBody Emp emp) {
    Emp e = empService.login(emp);
    if (e != null) { //用户名密码正确
        Map<String, Object> claims = new HashMap<>();
        claims.put("id", e.getId());
        claims.put("username", e.getUsername());
        claims.put("name", e.getName());
        //生成JWT令牌
        String jwt = JwtUtils.generateJwt(claims);
        //JwtUtils是已定义的工具类,调用它的令牌生成方法
        return Result.success(jwt);
    }
    return Result.error("用户名或密码错误");
}

前端浏览器会将返回的JWT令牌存储到浏览器本地,在后续的请求中在请求头中携带JWT令牌

在请求头中的token携带

暂无评论

发送评论 编辑评论


				
|´・ω・)ノ
ヾ(≧∇≦*)ゝ
(☆ω☆)
(╯‵□′)╯︵┴─┴
 ̄﹃ ̄
(/ω\)
∠( ᐛ 」∠)_
(๑•̀ㅁ•́ฅ)
→_→
୧(๑•̀⌄•́๑)૭
٩(ˊᗜˋ*)و
(ノ°ο°)ノ
(´இ皿இ`)
⌇●﹏●⌇
(ฅ´ω`ฅ)
(╯°A°)╯︵○○○
φ( ̄∇ ̄o)
ヾ(´・ ・`。)ノ"
( ง ᵒ̌皿ᵒ̌)ง⁼³₌₃
(ó﹏ò。)
Σ(っ °Д °;)っ
( ,,´・ω・)ノ"(´っω・`。)
╮(╯▽╰)╭
o(*////▽////*)q
>﹏<
( ๑´•ω•) "(ㆆᴗㆆ)
😂
😀
😅
😊
🙂
🙃
😌
😍
😘
😜
😝
😏
😒
🙄
😳
😡
😔
😫
😱
😭
💩
👻
🙌
🖕
👍
👫
👬
👭
🌚
🌝
🙈
💊
😶
🙏
🍦
🍉
😣
Source: github.com/k4yt3x/flowerhd
颜文字
Emoji
小恐龙
花!
上一篇
下一篇