JWT 认证校验 从理论到实战

一、JWT理论部分

1.JWT概述

JWT(JSON Web Token)是一个开放标准(RFC 7519),它定义了一种紧凑且自包含的方式,用于在各方之间以 JSON 对象的形式安全地传输信息。这种信息可以被验证和信任,因为它是数字签名的。JWT通常用于身份验证和授权,可以在浏览器和服务器之间传输,也可以在不同的系统之间传输。

JWT通常由三部分组成:

  • 头部(Header):一个JSON对象,描述了令牌的元数据,例如令牌的算法和类型。

  • 有效载荷(Payload):一个JSON对象,包含了令牌的声明,例如用户信息、发行人、过期时间等。

  • 签名(Signature):使用头部中指定的算法,对头部和有效载荷的Base64编码字符串进行加密,生成签名。

2.在通用模块下

导入jwt依赖

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

3.编写JWT的工具类:

signKey:密钥

expire:有效时长

最好使用@ConfigurationProperties,在所需要模块的application.yml中进行设置signKey和expire

public class JwtUtils {
 
    private static String signKey = "signKey";
    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)
                .getBody();
        return claims;
    }
}

4.JWT工具类(加入容器)

方式一:

在使用的类中,通过@Bean注解的方式

    @Bean
    public JwtUtils jwtUtils(){
        return new JwtUtils();
    }

方式二:

当你在 Spring Boot 应用程序中使用 @EnableAutoConfiguration 注解时,Spring Boot 会读取 META-INF/spring.factories 文件中定义的自动配置类。

在resource中创建文件夹META-INF,然后在其创建spring.factories文件

添加 单个

org.springframework.boot.autoconfigure.EnableAutoConfiguration=\
  com.etc.company.common.utils.JwtUtils

例如添加多个就使用(逗号和斜杠)进行分隔

org.springframework.boot.autoconfigure.EnableAutoConfiguration=\
  com.etc.common.config.RedisConfig,\
  com.etc.common.config.MyBatisConfig,\
  com.etc.company.common.utils.JwtUtils

二、JWT实战 

登录时,如果登录成功则获取返回的token值

    @Override
    public String loginUserByPassword(LoginDTO loginDTO) {

        User user = getUserByPhone(loginDTO.getPhone());

        if(Md5Util.checkPassword(loginDTO.getPhone()+loginDTO.getPassword(),user.getPassword())){
            Map<String, Object> claims = new HashMap<>();
            claims.put("id",user.getId());
            claims.put("phone",user.getPhone());
            String token = JwtUtils.generateJwt(claims);

            redisTemplate.opsForValue().set(token,token,2,TimeUnit.HOURS);
            return token;
        }
        return null;
    }

在拦截器中进行token校验:

@Component
public class LoginInterceptor implements HandlerInterceptor {

    @Autowired
    private RedisTemplate redisTemplate;
    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {

        String token = request.getHeader("Authorization");

        try{

            String redisToken  = (String) redisTemplate.opsForValue().get(token);
            if (redisToken == null){
                throw new ForbiddenException("token失效");
            }

            Claims claims = JwtUtils.parseJWT(token);

            //把业务数据存储到ThreadLocal中
            ThreadLocalUtil.set(claims);

            return true;
        }catch (Exception e){
            response.setStatus(401);
            return false;
        }

    }

    @Override
    public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
        //清空ThreadLocal中的数据
        ThreadLocalUtil.remove();
    }
}

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值