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. JWT 认证校验 理论实战

    2024-07-17 04:08:02       27 阅读
  2. SpringSecurity + JWT 实现登录认证

    2024-07-17 04:08:02       16 阅读
  3. JWT+Redis 实现接口 Token 校验

    2024-07-17 04:08:02       50 阅读

最近更新

  1. docker php8.1+nginx base 镜像 dockerfile 配置

    2024-07-17 04:08:02       67 阅读
  2. Could not load dynamic library ‘cudart64_100.dll‘

    2024-07-17 04:08:02       71 阅读
  3. 在Django里面运行非项目文件

    2024-07-17 04:08:02       58 阅读
  4. Python语言-面向对象

    2024-07-17 04:08:02       69 阅读

热门阅读

  1. vue3 学习笔记12 -- 插槽的使用

    2024-07-17 04:08:02       24 阅读
  2. PHP 包含

    2024-07-17 04:08:02       17 阅读
  3. 扫地机器人如何解决室内空气污染问题

    2024-07-17 04:08:02       18 阅读
  4. python 概述

    2024-07-17 04:08:02       17 阅读
  5. ChebNetII

    ChebNetII

    2024-07-17 04:08:02      14 阅读
  6. Linux工具应用_PERL

    2024-07-17 04:08:02       21 阅读
  7. 系统调用和库函数作业知识点整理

    2024-07-17 04:08:02       18 阅读
  8. 2024.7.16 刷题总结

    2024-07-17 04:08:02       17 阅读