软件编程
位置:首页>> 软件编程>> java编程>> Spring Boot整合JWT的实现步骤

Spring Boot整合JWT的实现步骤

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

标签:SpringBoot,整合JWT

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

0
投稿

猜你喜欢

手机版 软件编程 asp之家 www.aspxhome.com