JWT-springboot整合

57 阅读2分钟

JWT-springboot

demo地址

gitee.com/w--kk/jwt-s…

搭建springboot + mybatis + jwt环境

  • 引入依赖
<!-- 引入mybatis-->
<dependency>
    <groupId>org.mybatis.spring.boot</groupId>
    <artifactId>mybatis-spring-boot-starter</artifactId>
    <version>2.3.1</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</artifactId>
    <version>1.2.9</version>
</dependency>

<!-- mysql-->
<dependency>
    <groupId>mysql</groupId>
    <artifactId>mysql-connector-java</artifactId>
    <version>8.0.15</version>
</dependency>
  • 编写配置
#配置数据库
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?useUnicode=true&characterEncoding=UTF-8&serverTimezone=UTC&useSSL=false
spring.datasource.username=root
spring.datasource.password=123
#配置mybatis
mybatis.mapper-locations=classpath:com/kk/mapper/*.xml  #指定mapper配置文件位置
mybatis.type-aliases-package=com.wkk.entity     #指定起别名所在包
#配置日志使用
logging.level.root=info
logging.level.com.wkk=debug  #指定包日志
  1. 开发数据库 image.png
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;
  1. 开发entity
@Data
@Accessors(chain = true)
public class User {
    private Integer id;
    private String name;
    private String password;
}
  1. 开发DAO接口和mapper.xml
@Mapper
public interface UserDAO {
    //直接根据用户名密码登录
    User login(User user);
}
<mapper namespace="com.wkk.dao.UserDAO">
    <select id="login" parameterType="com.wkk.entity.User" resultType="com.wkk.entity.User">
        select *
        from user
        where name = #{name}
          and password = #{password}
    </select>
</mapper>
  1. 开发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("登录失败~");
    }
}

image.png

问题

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

使用拦截器优化

public class JWTInterceptor implements HandlerInterceptor {
    //jwt最好放在请求头里面,不要放在请求参数中
    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        Map<String, Object> map = new HashMap<>();
        //获取请求头中令牌
        String token = request.getHeader("token");
        try {
            //验证令牌
            JWTUtils.verify(token);
//            map.put("state", true);
//            map.put("msg", "请求成功");
            return true;  //放行请求
        } catch (SignatureVerificationException e) {  //签名不一致异常
            e.printStackTrace();
            map.put("msg", "无效签名");
        } catch (TokenExpiredException e) {  //令牌过期异常
            e.printStackTrace();
            map.put("msg", "令牌过期异常");
        } catch (AlgorithmMismatchException e) {  //算法不匹配异常
            e.printStackTrace();
            map.put("msg", "算法不匹配异常");
        } catch (Exception e) {
            e.printStackTrace();
            map.put("msg", "token无效!!");
        }
        map.put("state", false);  //设置状态
        //将map转为json  jackson
        String json = new ObjectMapper().writeValueAsString(map);
        response.setContentType("application/json;charset=UTF-8");
        response.getWriter().println(json);  //把对应的json发给前端
        return false;
    }
}

image.png

拦截器中要获取请求头中的token

image.png

获取token image.png

请求头带上token访问接口 image.png

image.png

引用
编程不良人