您好,登錄后才能下訂單哦!
本篇內容主要講解“SpringBoot集成JWT怎么實現token驗證”,感興趣的朋友不妨來看看。本文介紹的方法操作簡單快捷,實用性強。下面就讓小編來帶大家學習“SpringBoot集成JWT怎么實現token驗證”吧!
JWT可以理解為一個加密的字符串,里面由三部分組成:頭部(Header)、負載(Payload)、簽名(signature)
由base64加密后的header和payload使用.連接組成的字符串,然后通過header中聲明的加密方式進行加鹽secret組合加密,然后就構成了JWT字符串
往期介紹了JWT相關概念以及基本操作,接下來介紹如何在SpringBoot中整合JWT實現登陸注冊
<dependencies> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-test</artifactId> <scope>test</scope> </dependency> <!--引入mybatis--> <dependency> <groupId>org.mybatis.spring.boot</groupId> <artifactId>mybatis-spring-boot-starter</artifactId> <version>2.1.3</version> </dependency> <!--引入mysql--> <dependency> <groupId>mysql</groupId> <artifactId>mysql-connector-java</artifactId> <version>8.0.25</version> </dependency> <!--引入druid數據庫連接池--> <dependency> <groupId>com.alibaba</groupId> <artifactId>druid</artifactId> <version>1.2.1</version> </dependency> <!--引入lombok--> <dependency> <groupId>org.projectlombok</groupId> <artifactId>lombok</artifactId> <version>1.18.12</version> </dependency> <dependency> <groupId>org.mybatis.spring.boot</groupId> <artifactId>mybatis-spring-boot-starter-test</artifactId> <version>2.1.3</version> </dependency> <!--引入jwt--> <dependency> <groupId>com.auth0</groupId> <artifactId>java-jwt</artifactId> <version>3.4.0</version> </dependency> </dependencies>
有一個JWT庫,里面還有一個User表
server.port=8989 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?characterEncoding=utf8&useSSL=false&serverTimezone=UTC&rewriteBatchedStatements=true spring.datasource.username=root spring.datasource.password=12345678 #mybatis掃描的包 mybatis.type-aliases-package=com.ylc #mapper文件路徑 mybatis.mapper-locations=classpath:/**/*.xml #開啟sql打印日志 logging.level后面是mybatis對應的方法接口所在的包 logging.level.com.ylc.jwtdemo.dao=debug
import lombok.Data; @Data public class User { private String username; private String password; private int id; }
@Mapper public interface UserDao { User login(User user); }
public interface UserService { User login(User user);//登錄接口 }
import java.util.HashMap; import java.util.Map; @Service public class UserServiceImpI implements UserService { @Autowired private UserDao userDao; @Override public User login(User user) { User userdb=userDao.login(user); if(userdb!=null) { Map<String,String> map=new HashMap<>(); map.put("name",userdb.getUsername()); return userdb; } throw new RuntimeException("登錄失敗"); } }
@RestController 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 { userService.login(user); map.put("msg","登錄成功"); map.put("code","200"); } catch (Exception ex) { map.put("msg","登錄失敗"); } return map; } }
<?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"> <!--namespace 指的是要配置的全限定類名--> <mapper namespace="com.ylc.jwtdemo.dao.UserDao"> <select id="login" parameterType="com.ylc.jwtdemo.entity.User" resultType="com.ylc.jwtdemo.entity.User"> select *from user where username=#{username} and password=#{password} </select> </mapper>
/** * JWT工具類 * @author yanglingcong * @date 2021/12/31 11:24 AM */ public class JwtUtils { //鑒權 相當于私鑰保存在服務器上 private static final String secret="##@$%@#S#WS"; /** * 生成token * @author yanglingcong * @date 2021/12/31 11:23 AM * @param map * @return String */ public static String getToken(Map<String,String> map) { Calendar instance=Calendar.getInstance(); //默認七天過期 instance.add(Calendar.DATE,7); //創建JWT JWTCreator.Builder builder = JWT.create(); //payload map.forEach((k,v)->{ builder.withClaim(k,v); }); //指定令牌過期時間 builder.withExpiresAt(instance.getTime()); String token=builder.sign(Algorithm.HMAC256(secret)); return token; } /** * 驗證token * @author yanglingcong * @date 2021/12/31 11:26 AM * @param token */ public static DecodedJWT verify(String token) { return JWT.require(Algorithm.HMAC256(secret)).build().verify(token); } }
整個項目概覽
測試驗證是否能夠連通數據庫
訪問:localhost:8989/user/login?username=ylc&password=123456
@Slf4j @RestController 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 { userService.login(user); map.put("msg","登錄成功"); map.put("code","200"); Map<String,String> payload=new HashMap<>(); payload.put("name",user.getUsername()); String token= JwtUtils.getToken(payload); map.put("token",token); } catch (Exception ex) { map.put("msg","登錄失敗"); } return map; } @PostMapping("/test/verity") public Map<String,String> verityToken(String token) { Map<String, String> map=new HashMap<>(); log.info("token為"+token); try { DecodedJWT verify = JwtUtils.verify(token); map.put("msg","驗證成功"); map.put("state","true"); } catch (Exception exception) { map.put("msg","驗證失敗"); exception.printStackTrace(); } return map; } }
訪問:http://localhost:8989/user/login?username=ylc&password=123456
訪問:http://localhost:8989/test/verity
但是我們這樣寫在實際項目中是不合理的,把token生成的代碼放在了Controller中,業務邏輯是不能放在Controller層中的。假如很多接口都需要token來進行驗證保護,那每一個接口都需要添加這樣一段代碼,造成代碼冗余。
如果是web項目使用攔截器進行優化,如果是springcloud項目在網關層進行攔截,下面演示如何使用攔截器攔截
最好還把JWT生成token放在http請求頭,這樣就不需要把token當成參數傳遞了
新建一個攔截器JwtInterceptor
/** * JWT攔截器 * @author yanglingcong * @date 2021/12/31 12:39 PM */ public class JwtInterceptor implements HandlerInterceptor { @Override public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception { HashMap<String, String> map=new HashMap<>(); //從http請求頭獲取token String token = request.getHeader("token"); try { //如果驗證成功放行請求 DecodedJWT verify = JwtUtils.verify(token); return true; } catch (Exception exception) { map.put("msg","驗證失敗:"+exception); } String json = new ObjectMapper().writeValueAsString(map); response.setContentType("application/json:charset=UTF=8"); response.getWriter().println(json); return false; } }
然后把攔截器注冊到過濾器中,新建一個過濾器InterceptConfig
/** * @author yanglingcong */ @Configuration public class InterceptConfig implements WebMvcConfigurer { @Override public void addInterceptors(InterceptorRegistry registry) { //添加攔截器 registry.addInterceptor(new JwtInterceptor()) //攔截的路徑 需要進行token驗證的路徑 .addPathPatterns("/test/verity") //放行的路徑 .excludePathPatterns("/user/login"); } }
登錄是不需要攔截的,其他請求如果有需要驗證token就放入攔截器的路徑
在http請求頭中放入token,會被攔截器攔截驗證token的有效性
到此,相信大家對“SpringBoot集成JWT怎么實現token驗證”有了更深的了解,不妨來實際操作一番吧!這里是億速云網站,更多相關內容可以進入相關頻道進行查詢,關注我們,繼續學習!
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。