java中使用JWT

本文详细介绍了JWT的工作原理,包括其组成部分(头信息、有效载荷和签名)、Java实现示例,并探讨了在实际开发中的应用,如用户登录验证与token管理。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

JWT:JSON Web Token,是通过数字签名,以JSON对象为载体在服务间安全传输信息的方式。JWT由三部分组成:头信息、有效载体和签名。头信息包括:令牌类型和签名算法信息;有效载体是使用一个JSON对象作为数据内容,由于只是采用base64运算,并没有进行加密,因此通常存放一些非敏感数据;签名是采用不可逆签名算法对base64后的头信息拼接上点拼接上base64后的有效载体及签名秘钥进行运算得出,防止token信息被篡改,最后生成的Token是由base64后的头信息拼接上点拼接上base64后的有效载体拼接上点拼接上base64后的签名信息组成。

JWT组成:

// javascript
var encodedString = base64UrlEncode(header) + '.' + base64UrlEncode(payload);

var signature = HMACSHA256(encodedString, 'secret'); // TJVA95OrM7E2cBab30RMHrHDcEfxjoYZgeFONFh7HgQ

将这三部分用.连接成一个完整的字符串,构成了最终的jwt:

  eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiYWRtaW4iOnRydWV9.TJVA95OrM7E2cBab30RMHrHDcEfxjoYZgeFONFh7HgQ

 

JAVA程序使用JWT

        <dependency>
            <groupId>com.auth0</groupId>
            <artifactId>java-jwt</artifactId>
            <version>3.10.3</version>
        </dependency>
        <dependency>
            <groupId>io.jsonwebtoken</groupId>
            <artifactId>jjwt</artifactId>
            <version>0.9.1</version>
        </dependency>
package com.tech.jwt.utils;

import com.tech.jwt.domain.User;
import io.jsonwebtoken.*;

import java.util.Date;
import java.util.UUID;

/**
 * @author lw
 * @since 2021/12/29
 */
public class JwtUtil {
    
    private static final String secretKey="hello jwt key";
    
    /**
     * 生成 JWT TOKEN
     * @param user 用户信息
     * @return String token
     */
    public static String createToken(User user){
        JwtBuilder jwtBuilder = Jwts.builder();
        String token = jwtBuilder
                //header
                .setHeaderParam("typ", "JWT")
                .setHeaderParam("alg", "HS256")
                //payload
                .claim("userId", user.getUserId())
                .claim("userName", user.getUserName())
                .claim("role", user.getRole())
                .setSubject("admin-test")
                .setExpiration(new Date(System.currentTimeMillis() + 1000 * 60 * 60))
                .setId(UUID.randomUUID().toString())
                //signature
                .signWith(SignatureAlgorithm.HS256, secretKey)
                .compact();
        return token;
    }

    /**
     * 解析 JWT TOKEN
     * @param token JWT TOKEN
     * @return User user
     */
    public static User parse(String token){
        JwtParser parser = Jwts.parser();
        Jws<Claims> claimsJws = parser.setSigningKey(secretKey).parseClaimsJws(token);
        Claims claims = claimsJws.getBody();
        System.out.println(claims.get("userId"));
        System.out.println(claims.get("userName"));
        System.out.println(claims.get("role"));
        System.out.println(claims.getId());
        System.out.println(claims.getSubject());
        System.out.println(claims.getExpiration());
        User user=new User();
        user.setUserId(Long.valueOf(claims.get("userId").toString()));
        user.setUserName((String)claims.get("userName"));
        user.setRole((String)claims.get("role"));
        return user;
    }

    public static void main(String[] args) {
        User user = new User();
        user.setUserId(1L);
        user.setUserName("张三");
        user.setRole("admin");
        String token = createToken(user);
        System.out.println(token);

        User u = parse(token);
        System.out.println(u);
    }
}
package com.tech.jwt.domain;

import lombok.Data;

/**
 * @author lw
 * @since 2021/12/29
 */
@Data
public class User {
    private Long userId;
    private String userName;
    private String userPwd;
    private String role;

    @Override
    public String toString() {
        return "User{" +
                "userId=" + userId +
                ", userName='" + userName + '\'' +
                ", userPwd='" + userPwd + '\'' +
                ", role='" + role + '\'' +
                '}';
    }
}
package com.tech.jwt.controller;

import com.tech.jwt.domain.User;
import com.tech.jwt.utils.JwtUtil;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestHeader;
import org.springframework.web.bind.annotation.RestController;

/**
 * @author lw
 * @since 2021/12/29
 */
@RestController
public class UserController {

    /**
     * 登录 
     * @param user user
     * @return jwt token
     */
    @GetMapping("login")
    String login(User user){
        //去数据库查询校验登录信息
        if(user.getUserName().equals("admin") && user.getUserPwd().equals("123")){
            user.setUserId(1L);
            user.setRole("admin");
            return JwtUtil.createToken(user);
        }
        return null;
    }

    /**
     * 校验 jwt token 
     * 通常在拦截器中校验
     * @param token jwt token
     * @return 校验结果
     */
    @GetMapping("valid")
    boolean valid(@RequestHeader("token") String token ){
        try {
            JwtUtil.parse(token);
        } catch (Exception e) {
            return false;
        }
        return true;
    }
}

封装了一个JWT工具类提供创建JWT Token和解析JWT Token的方法,登录接口,根据用户提交的登录信息,校验通过后生成JWT Token,客户端保存token,以后访问服务时需要在请求头中携带token。Token校验接口,在拦截器中进行处理,应用程序访问服务时在拦截器校验Header中携带token的有效性,如果有效则返回请求的服务资源,如果无效则返回认证失败。

一般是在请求头里加入Authorization,并加上Bearer标注:

fetch('api/user/1', {
  headers: {
    'Authorization': 'Bearer ' + token
  }
})

服务端会验证token,如果验证通过就会返回相应的资源。整个流程就是这样的: 

 

在实际开发中,用户登录校验成功后会随机生成一个key,比如uuid,使用这个随机生成的key作为key,用户信息作为value,保存在Redis中,并设置失效时间。然后创建一个JWT TOKEN,使用随机生成的key作为jwt的有效载体,将生成好的JWT Token返给前端,前端保存在本地,当访问后端服务时,前端需要在请求头中携带 jwt token,后端通过拦截器对请求进行拦截,校验token是否有效,如果token有效,则在jwt token的有效载体中获取key,然后使用该key在redis中查找是否存在,如果存在说明登录验证通过,如果不存在说明验证登录信息已过期。

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值