JWT整合Springboot

一.封装工具类

public class JWTUtils {

    /**
     * 盐值
     */
    private static final String SING="huang@1024955508";
    
    /**
     * 生成令牌
     * @param map payload载荷声明参数
     * @return
     */
    public  static String getToken(Map<String,String> map){
        //获取日历对象
        Calendar calendar=Calendar.getInstance();
        //默认7天过期
        calendar.add(Calendar.DATE, 7);
        //新建一个JWT的Builder对象
        JWTCreator.Builder builder = JWT.create();
        //将map集合中的数据设置进payload
        map.forEach((k,v)->{
            builder.withClaim(k, v);
        });
        //设置过期时间和签名
        String sign = builder
                .withExpiresAt(calendar.getTime())
                .sign(Algorithm.HMAC256(SING));

        return sign;
    }

    /**
     * 验签并返回DecodedJWT
     * @param token  令牌
     */
    public  static DecodedJWT verify(String token){
        return JWT.require(Algorithm.HMAC256(SING)).build().verify(token);
    }

}

二.整合springboot

搭建springboot+mybatis+jwt环境

  • 引入依赖
  • 编写配置
<dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter</artifactId>
        </dependency>

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>

        <!--JWT的依赖-->
        <dependency>
            <groupId>com.auth0</groupId>
            <artifactId>java-jwt</artifactId>
            <version>3.4.0</version>
        </dependency>
        <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
        </dependency>


        <!--引入mybatis-->
        <dependency>
            <groupId>org.mybatis.spring.boot</groupId>
            <artifactId>mybatis-spring-boot-starter</artifactId>
            <version>2.1.3</version>
        </dependency>

        <!--引入lombok-->
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <version>1.18.12</version>
        </dependency>

        <!--引入druid-->
        <dependency>
            <groupId>com.alibaba</groupId>
            <artifactId>druid-spring-boot-starter</artifactId>
            <version>1.2.6</version>
        </dependency>
        <!--引入mysql-->
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <scope>runtime</scope>
        </dependency>
        <!--jdbc-->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-jdbc</artifactId>
        </dependency>


        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
server.port=8080
spring.application.name=jwt

spring.datasource.type=com.alibaba.druid.pool.DruidDataSource
spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver
spring.datasource.url=jdbc:mysql://localhost:3306/jwt?serverTimezone=UTC&useUnicode=false&characterEncoding=utf-8
spring.datasource.username=root
spring.datasource.password=123456

mybatis.type-aliases-package=com.huang.pojo
mybatis.mapper-locations=classpath:mapper/*.xml

logging.level.com.huang.dao=debug

1.数据库

这里采用最简单的表结构验证JWT使用

DROP TABLE IF EXISTS `user`;
CREATE TABLE `user` (
  `id` int(11) NOT NULL AUTO_INCREMENT COMMENT '主键',
  `name` varchar(80) DEFAULT NULL COMMENT '用户名',
  `password` varchar(40) DEFAULT NULL COMMENT '用户密码',
  PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=2 DEFAULT CHARSET=utf8;

2.pojo

@Data
@Accessors(chain=true)
public class User {
    private String id;
    private String name;
    private String password;
}

3.开发DAO接口和mapper.xml

@Mapper
public interface UserDAO {
    User login(User user);
}
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
        PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
        "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.huang.dao.UserDao">
   
    <select id="login" parameterType="User" resultType="User">
        select * from jwt.user where name=#{name} and password = #{password}
    </select>
</mapper>

4.开发Service 接口以及实现类

public interface UserService {
    User login(User user);//登录接口
}
@Service
@Transactional
public class UserServiceImpl implements UserService {
    @Autowired
    private UserDAO userDAO;
    @Override
    @Transactional(propagation = Propagation.SUPPORTS)
    public User login(User user) {
        User userDB = userDAO.login(user);
        if(userDB!=null){
            return userDB;
        }
        throw  new RuntimeException("登录失败~~");
    }
}

5.开发controller

@RestController
public class UserController {

    @Autowired
    private UserService userService;

    @GetMapping("/user/login")
    public Map<String,Object> login(User user){
        System.out.println(user.getName());
        System.out.println(user.getPassword());

        Map<String,Object> map=new HashMap<>();


        try {
            User userDB = userService.login(user);
            HashMap<String, String> payload = new HashMap<>();  //存放payload
            payload.put("name",userDB.getName());
            payload.put("password",userDB.getPassword());
            map.put("state",true);
            map.put("msg","用户密码正确成功");
            
            //认证成功,生成token令牌
            map.put("token",JWTUtils.getToken(payload));
        } catch (Exception e) {
            map.put("state",false);
            map.put("msg",e.getMessage());
        }

        return map;
    }


    @GetMapping("/user/test")
    public Map<String,Object> test(){
        HashMap<String, Object> map = new HashMap<>();
        map.put("msg","令牌验证成功");
        return map;
    }
}

6.编写JWT拦截器

  • 使用上述方式每次都要传递token数据,每个方法都需要验证token代码冗余,不够灵活? 如何优化
  • 使用拦截器进行优化
public class JwtInterceptor implements HandlerInterceptor {

    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        //获取请求头中的令牌
        String token = request.getHeader("token");
        HashMap<String, Object> map = new HashMap<>();
        try {
            JWTUtils.verify(token);
            return true;
        } catch (TokenExpiredException e) {

            map.put("msg", "Token已经过期!!!");
        } catch (SignatureVerificationException e){

            map.put("msg", "签名错误!!!");
        } catch (AlgorithmMismatchException e){

            map.put("msg", "加密算法不匹配!!!");
        } catch (Exception e) {
            e.printStackTrace();

            map.put("msg", "无效token~~");
        }
        map.put("state",false);  //设置状态
        //将map转为json
        String json = new ObjectMapper().writeValueAsString(map);
        response.setContentType("application/json;charset=UTF-8");
        response.getWriter().println(json);
        return false;

    }
}

7.编写拦截器配置类

@Configuration
public class InterceptorConfig implements WebMvcConfigurer {

    @Override
    public void addInterceptors(InterceptorRegistry registry) {
        registry.addInterceptor(new JwtInterceptor()) //添加拦截器
               // .addPathPatterns("/**")  //拦截路径
               // .excludePathPatterns("/user/**"); //不拦截路径
                .addPathPatterns("/user/test")  //拦截路径
                .excludePathPatterns("/user/login"); //不拦截路径


    }
}

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值