JWT的应用

主要内容:

1.生成JWT工具类

2.配置过滤器

3.注册过滤器

4.配置全局异常类

5.测试

引入JWT依赖:

        <!-- jwt -->
        <dependency>
            <groupId>io.jsonwebtoken</groupId>
            <artifactId>jjwt</artifactId>
            <version>0.9.1</version>
        </dependency>

本项目中会用到 fastjson工具依赖,用来将Result 响应结果对象转化成 json对象返回给前端

        <dependency>
            <groupId>com.alibaba</groupId>
            <artifactId>fastjson</artifactId>
            <version>1.2.54</version>
        </dependency>

1.生成JWT工具类

@Data
@Component
public class JwtUtils {
    private String secretId = "are3gh3456jint765ydh45mxj7ie5j6i";
    private long expire = 7;
    private String header = "token";

    // 根据用户名生成jwt
    public String createToken(String username) {
        // 1.定义header
        Map headerMap = new HashMap();
        headerMap.put("alg", SignatureAlgorithm.HS256.getValue());
        headerMap.put("typ", "JWT");

        // 2.定义payload
        Date nowDate = new Date();
        Date expireDate = new Date(nowDate.getTime() + expire * 1000 * 24 * 60 * 60);

        // 3.生成token
        return Jwts.builder()
                .setHeaderParams(headerMap)
                .setSubject(username)
                .setIssuedAt(nowDate)
                .setExpiration(expireDate)
                .signWith(SignatureAlgorithm.HS256, secretId)
                .compact();
    }

    // 解析jwt
    public Claims getToken(String token) {
        try {
            return Jwts.parser()
                    .setSigningKey(secretId)
                    .parseClaimsJws(token)
                    .getBody();
        } catch (Exception e) {
            return null;
        }
    }

    // 验证token是否过期
    public boolean isTokenExpired(Date expirationTime) {
        return expirationTime.before(new Date());
    }

    // 获取token 过期时间
    public Date getExpirationDateFromToken(String token) {
        return getToken(token).getExpiration();
    }

    // 获取用户名
    public String getUsernameFromToken(String token) {
        return getToken(token).getSubject();
    }

    // 获取jwt发布时间
    public Date getIssuedAtDateFromToken(String token) {
        return getToken(token).getIssuedAt();
    }
}

2.配置过滤器

@Slf4j
@Component
public class TokenInterceptor implements HandlerInterceptor {
    @Resource
    private JwtUtils jwt;

    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        // 1.地址过滤
        String url = request.getRequestURI();
        if (url.contains("/login")) {
            log.info("登录请求,放行");
            return true;
        }
        // 2.token验证
        //  3.获取请求头中的令牌
        String token = request.getHeader(jwt.getHeader());
        //  4.判断令牌是否存在
        if (!StringUtils.isEmpty(token)) {
            // 5.令牌不存在
            log.info("请求头token为空,返回");
            Result loginerr = Result.error("NOT_NOLOGIN");
            // 把对象转换为JSON返回
            String nologin = JSONObject.toJSONString(loginerr);
            response.getWriter().write(nologin);
            return false;
        }
        // 6.令牌存在,但是令牌可能过期
        Claims claims = null;
        try {
            claims = jwt.getToken(token);
            if (claims == null || jwt.isTokenExpired(claims.getExpiration())) {
                throw new SignatureException(jwt.getHeader() + "token失效");
            }
        } catch (Exception e) {
            throw new SignatureException(jwt.getHeader() + "tokne失效");
        }
        //设置identityId 用户身份ID
        request.setAttribute("identityId",claims.getSubject());
        return true;
    }
}

3.注册过滤器

@Configuration
public class WebConfig implements WebMvcConfigurer {
    @Autowired
    private TokenInterceptor tokenInterceptor;

    @Override
    public void addInterceptors(InterceptorRegistry registry) {
        registry.addInterceptor(tokenInterceptor).addPathPatterns("/**").excludePathPatterns("/login");
    }
}

4.配置全局异常类

@RestControllerAdvice
public class GlobalException {
    @ExceptionHandler(value = {SignatureException.class})
    @ResponseBody
    public Result authorizationException(SignatureException e) {
        return Result.error( "error");
    }
}

5.测试

@RestController
public class loginController {
    @Resource
    private JwtUtils jwtUtils;

    @PostMapping("/login")
    public Result login(String username, String password) {
        JSONObject json = new JSONObject();
        // 模拟从数据库中查询用户名,和密码
        String user = "老朱";
        String token = jwtUtils.createToken(user);
        if (!StringUtils.isEmpty(token)) {
            json.put("token", token);
        }
        return Result.success(json);
    }

    // 请求其它接口
    @PostMapping("/info")
    public Result info() {
        return Result.success("info");
    }

    // 将token放到请求头中 来请求
    @GetMapping("/getuser")
    public Result getUserInfo(HttpServletRequest request) {
        String username = jwtUtils.getUsernameFromToken(request.getHeader("token"));
        return Result.success(username);
    }
}

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值