首先,介紹一下什么是JWT
Json web token (JWT), 是為了在網路應用環境間傳遞宣告而執行的一種基于JSON的開放標準((RFC 7519).定義了一種簡潔的,自包含的方法用于通信雙方之間以JSON物件的形式安全的傳遞資訊,因為數字簽名的存在,這些資訊是可信的,JWT可以使用HMAC演算法或者是RSA的公私秘鑰對進行簽名
JWT請求流程
1. 用戶使用賬號密碼發出post請求;
2. 服務器使用私鑰創建一個jwt;
3. 服務器回傳這個jwt給瀏覽器;
4. 瀏覽器將該jwt串在請求頭中像服務器發送請求;
5. 服務器驗證該jwt;
6. 回傳回應的資源給瀏覽器,
JWT標準的Token有三個部分組成,分別是
header:header 部分主要是兩部分內容,一個是 Token 的型別,另一個是使用的演算法,比如下面型別就是 JWT,使用的演算法是 HS256,就是SHA-256,和md5一樣是不可逆的散列演算法,
payload:Payload 里面是 Token 的具體內容
signature:簽名,在服務器端,用簽名做token校驗
springboot整合JWT
引入需要的依賴
<dependency>
<groupId>com.auth0</groupId>
<artifactId>java-jwt</artifactId>
<version>3.10.3</version>
</dependency>
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>mybatis-plus-boot-starter</artifactId>
<version>3.2.0</version>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<scope>runtime</scope>
<version>5.1.32</version>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>1.18.12</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>fastjson</artifactId>
<version>1.2.73</version>
</dependency>
JWT 工具類
/**
* @author dugt1998@163.com
* @date 2020/11/8 12:40
*/
public class JWTUtils {
//簽名 自己專案中的簽名
private static final String SIGN = "token!@19weawe2r24@#$@%!wewa98du";
/**
* 生成token
*
* @param claim 傳入的payload
* @return
*/
public static String getToken(Map<String, String> claim) {
JWTCreator.Builder builder = JWT.create();
/*
* 1、header 用默認的就可
* 2、設定payload .withClaim
* 3、設定簽名 .sign
*/
claim.forEach((key, value) -> {
builder.withClaim(key, value); //設定payload
});
Calendar instance = Calendar.getInstance();
instance.add(Calendar.DAY_OF_MONTH, 7);
builder.withExpiresAt(instance.getTime()); //設定token過期時間
return builder.sign(Algorithm.HMAC256(SIGN));
}
/**
* 校驗令牌
*
* @param token
*/
public static DecodedJWT verifyToken(String token) {
return JWT.require(Algorithm.HMAC256(SIGN)).build().verify(token);
}
}
使用攔截器攔截處理token
/**
* @author dugt1998@163.com
* @date 2020/11/8 13:26
*/
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.verifyToken(token);
return true;
} catch (SignatureVerificationException e) {
/**
* SignatureVerificationException :簽名不一致例外
* TokenExpiredException: 令牌過期例外
* AlgorithmMismatchException:演算法不匹配例外
* InvalidClamException 失效的payload例外
*/
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("status",false);
String errorMsg = JSONObject.toJSONString(map);
response.setContentType("application/json; charset=UTF-8");
PrintWriter writer = response.getWriter();
writer.print(errorMsg);
writer.close();
return false;
}
}
開啟攔截器
/**
* <p>
*
* </p>
*
* @author dugt1998@163.com
* @date 2020/11/9 9:46
*/
@Configuration
public class InterceptorConfig implements WebMvcConfigurer {
@Override
public void addInterceptors(InterceptorRegistry registry) {
registry.addInterceptor(jwtInterceptor())
.addPathPatterns("/*")
.excludePathPatterns("/user/login");
}
@Bean
public JWTInterceptor jwtInterceptor(){
return new JWTInterceptor();
}
}
用戶登錄認證授權token資訊
/**
* 認證
* @param user
* @param request
* @return
*/
@PostMapping("/login")
public Map<String, Object> login(User user, HttpServletRequest request) {
HashMap<String, Object> map = new HashMap<>();
QueryWrapper<User> wrapper = new QueryWrapper<>();
wrapper.eq("username", user.getUsername());
wrapper.eq("password", user.getPassword());
try {
User currUser = userMapper.selectOne(wrapper);
HashMap<String, String> claim = new HashMap<>();
claim.put("id",currUser.getId());
claim.put("username",currUser.getUsername());
String token = JWTUtils.getToken(claim);
map.put("status",true);
map.put("msg","認證成功");
map.put("token",token);
return map;
} catch (Exception e) {
map.put("status",false);
map.put("msg","認證失敗");
return map;
}
}
最后寫一個介面測驗一下
/**
* 模擬請求的介面
* @return
*/
@GetMapping
public String get(){
return "成功請求";
}
當不攜帶token訪問該介面時

認證獲取token

攜帶token 訪問測驗介面

請求成功!!!
使用ajax攜帶token
$.ajax({
headers: {
"token":token
},
type: "get",
url: "/test/getMessage",
contentType: "application/x-www-form-urlencoded",
})
這世上沒有天才,你若對得起時間,時間便對得起你,讓我們一起攜手共進,每天進步一點點,利用碎片化時間學習,
轉載請註明出處,本文鏈接:https://www.uj5u.com/qita/208545.html
標籤:其他
