Spring Boot整合JWT的实现步骤

作者:定格&不褪 时间:2022-07-17 04:48:58 

springboot整合jwt步骤:

1、登录时,验证账号和密码成功后,生成jwt,返回给前端;
2、前端接收后保存,再做其他操作,比如增删改查时,同时将jwt传给后端进行验证,如果jwt当做参数一起传给后端,那么每个操作都会有jwt,为了方便,把jwt放到请求头中,通过 * 来验证。

代码

代码结构图如下,除了常规的controller、entity、mapper和service层,还有两个 * 和注册 * ,图中用红字进行注释(这篇文章稍微有点长,因为我把代码都放上来了,结合下边的思路和结构图就能理解个大概)。

思路:有请求过来,通过 * 进行拦截,但放行登录请求,如果登录成功,生成JWT令牌,返回给前端,当前端再有其他请求过来时, * 会拦截并解析token,如果通过就允许业务操作,否则就返回相应提示信息。

Spring Boot整合JWT的实现步骤

1、创建jwt数据库,然后创建user表


CREATE TABLE `user` (
 `id` int(11) NOT NULL AUTO_INCREMENT,
 `username` varchar(255) DEFAULT NULL,
 `password` varchar(255) DEFAULT NULL,
 PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=3 DEFAULT CHARSET=utf8mb4;

插入数据


INSERT INTO `user` VALUES (1, 'zhangsan', '123');
INSERT INTO `user` VALUES (2, 'lisi', '123');

2、创建Spring Boot项目,在pom文件中,添加jwt等一些依赖和properties:


       <!--jwt-->
       <dependency>
           <groupId>com.auth0</groupId>
           <artifactId>java-jwt</artifactId>
           <version>3.4.0</version>
       </dependency>
       <dependency>
           <groupId>org.projectlombok</groupId>
           <artifactId>lombok</artifactId>
       </dependency>

<dependency>
           <groupId>org.mybatis.spring.boot</groupId>
           <artifactId>mybatis-spring-boot-starter</artifactId>
           <version>2.1.4</version>
       </dependency>
       <dependency>
           <groupId>com.alibaba</groupId>
           <artifactId>druid</artifactId>
           <version>1.2.4</version>
       </dependency>
       <!--我的mysql是5.6,所以这里是5.1版本-->
       <dependency>
           <groupId>mysql</groupId>
           <artifactId>mysql-connector-java</artifactId>
           <version>5.1.47</version>
       </dependency>
       <dependency>
           <groupId>org.springframework</groupId>
           <artifactId>spring-tx</artifactId>
           <version>5.3.8</version>
       </dependency>

编写application.properties


server.port=8899
spring.application.name=jwt

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

mybatis.type-aliases-package=com.jwt.entity
mybatis.mapper-locations=classpath:mapper/*Mapper.xml

#打印sql
logging.level.com.jwt.mapper=debug

3、编写代码

3.1、编写entity包下的User


public class User {
   private String id;
   private String username;
   private String password;
   //省略了get和set方法
}

3.2、编写util包下的JWTUtils


public class JWTUtils {

private static final String SING = "lu123456";

/**
    * 生成token
    */
   public static String getToken(Map<String,String> map){
       Calendar instance = Calendar.getInstance();
       //默认7天过期
       instance.add(Calendar.DATE,7);
       //创建jwt builder
       JWTCreator.Builder builder = JWT.create();

map.forEach((k,v)->{
           builder.withClaim(k,v);
       });

String token = builder.withExpiresAt(instance.getTime())
               .sign(Algorithm.HMAC256(SING));
       return token;
   }

/**
    * 验证token合法性
    */
   public static DecodedJWT verify(String token){
       return JWT.require(Algorithm.HMAC256(SING)).build().verify(token);
   }
}

3.3、编写controller层下UserController


@RestController
@Slf4j
public class UserController {
   @Autowired
   private UserService userService;

@GetMapping("/user/login")
   public Map<String,Object> login(User user){
       log.info("用户名:[{}]",user.getUsername());
       log.info("密码:[{}]",user.getPassword());

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

try {
           User userDB = userService.login(user);
           Map<String,String> payload = new HashMap<>();
           payload.put("id",userDB.getId());
           payload.put("username",userDB.getUsername());
           //生成JWT令牌
           String token = JWTUtils.getToken(payload);
           map.put("state",true);
           map.put("token",token);
           map.put("msg","认证成功");
       }catch (Exception e){
           map.put("state",false);
           map.put("msg",e.getMessage());
       }
       return map;
   }

@PostMapping("/user/test")
   public Map<String,Object> test(String token){
       Map<String, Object> map = new HashMap<>();
       map.put("state",true);
       map.put("msg","请求成功");
       return map;
   }
}

3.4、编写service层下UserService类和UserServiceImpl


public interface UserService {
   User login (User user);
}

实现类:


@Service
public class UserServiceImpl implements UserService {

@Autowired
   private UserMapper userMapper;

@Override
   @Transactional(propagation = Propagation.SUPPORTS)
   public User login(User user) {
       //查询数据库
       User userDB = userMapper.login(user);
       if (userDB != null){
           return userDB;
       }
       throw new RuntimeException("登录失败");
   }
}

3.5、编写mapper层的UserMapper


@Mapper
public interface UserMapper {
   User login(User user);
}

3.6、编写与UserMapper 对应的UserMapper.xml


<?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.jwt.mapper.UserMapper">

<select id="login" parameterType="com.jwt.entity.User" resultType="com.jwt.entity.User">
       SELECT * FROM user WHERE username = #{username} AND password = #{password}
   </select>

</mapper>

3.7、配置 * ,这样得到jwt后,再次请求时把jwt放到请求头中,就可以不用当参数传递。
编写JWTInterceptor类:


/**
* 配置 *
*/
public class JWTInterceptor implements HandlerInterceptor {
   @Override
   public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
       Map<String, Object> map = new HashMap<>();

//获取请求头中的令牌
       String token = request.getHeader("token");

try {
           //验证令牌
           DecodedJWT verify = JWTUtils.verify(token);
           return true;
       } catch (SignatureVerificationException e){
           e.printStackTrace();
           map.put("msg","无效签名");
       } catch (TokenExpiredException e){
           e.printStackTrace();
           map.put("msg","token过期");
       } catch (AlgorithmMismatchException e){
           e.printStackTrace();
           map.put("msg","token算法不一致");
       } catch (Exception e){
           e.printStackTrace();
           map.put("msg","token无效");
       }
       map.put("state","flase");

//将map转为json
       String json = new ObjectMapper().writeValueAsString(map);
       response.setContentType("application/json;charset=UTF-8");
       response.getWriter().println(json);
       return false;
   }
}

编写InterceptorConfig类:


/**
* 注册 *
*/
@Configuration
public class InterceptorConfig implements WebMvcConfigurer {
   @Override
   public void addInterceptors(InterceptorRegistry registry) {
       registry.addInterceptor(new JWTInterceptor())
               //拦截
               .addPathPatterns("/user/test")
               //放行
               .excludePathPatterns("/user/login");
   }
}

4、测试

运行程序后,使用postman进行测试,登录如下图
请求方式:get
url:http://localhost:8899/user/login?username=zhangsan&password=123
然后点击send,就会看到返回成功和token

Spring Boot整合JWT的实现步骤

请求测试
请求方式:post
url:http://localhost:8899/user/test
点击header,在请求头中添加token,然后点击send

Spring Boot整合JWT的实现步骤

来源:https://blog.csdn.net/qq_42524288/article/details/119391816

标签:SpringBoot,整合JWT
0
投稿

猜你喜欢

  • 解决springboot配置logback-spring.xml不起作用问题

    2022-09-10 11:21:24
  • 基于Java接口回调详解

    2023-11-09 00:03:11
  • SpringMVC @NotNull校验不生效的解决方案

    2021-07-19 23:20:07
  • Java读取并下载网络文件的方法

    2023-03-18 11:47:05
  • 微服务通过Feign调用进行密码安全认证操作

    2023-07-30 02:43:38
  • c#方法重写和隐藏的学习示例

    2022-12-24 14:20:12
  • Jetpack Compose 的新型架构 MVI使用详解

    2023-01-24 14:53:26
  • PC蓝牙通信C#代码实现

    2023-07-06 19:59:32
  • Flutter中http请求抓包的完美解决方案

    2023-08-22 18:47:47
  • SpringCloud之Feign示例详解

    2023-03-16 06:14:32
  • Java URL自定义私有网络协议

    2021-08-11 02:21:06
  • C#访问C++动态分配的数组指针(实例讲解)

    2021-08-20 10:34:27
  • c# WPF中的TreeView使用详解

    2021-05-24 15:17:58
  • C# InitializeComponent()方法案例详解

    2022-06-12 03:07:06
  • Spring Security中使用authorizeRequests遇到的问题小结

    2023-10-07 04:23:45
  • java二维码生成的方法

    2022-08-02 22:07:28
  • SpringBoot如何动态修改Scheduled(系统启动默认执行,动态修改)

    2023-11-29 06:13:27
  • 详细介绍Android-Room数据库的使用

    2022-10-30 09:10:53
  • 详解Java二叉排序树

    2022-05-25 03:14:26
  • Java注解之Elasticsearch的案例详解

    2022-03-30 12:28:58
  • asp之家 软件编程 m.aspxhome.com