SpringBoot集成JWT生成token及校驗(yàn)方法過(guò)程解析
GitHub源碼地址:https://github.com/zeng-xian-guo/springboot_jwt_token.git
封裝JTW生成token和校驗(yàn)方法
public class JwtTokenUtil {
//公用密鑰-保存在服務(wù)端,客戶端是不會(huì)知道密鑰的,以防被攻擊
public static String SECRET = "ThisIsASecret";
//生成Troke
public static String createToken(String username) {
//簽發(fā)時(shí)間
//Date iatDate = new Date();
//過(guò)地時(shí)間 1分鐘后過(guò)期
//Calendar nowTime = Calendar.getInstance();
//nowTime.add(Calendar.MINUTE, 1);
//Date expiresDate = nowTime.getTime();
Map<String, Object> map = new HashMap();
map.put("alg", "HS256");
map.put("typ", "JWT");
String token = JWT.create()
.withHeader(map)
//.withClaim( "name","Free碼生") //設(shè)置 載荷 Payload
//.withClaim("age","12")
//.withClaim( "org","測(cè)試")
//.withExpiresAt(expiresDate)//設(shè)置過(guò)期時(shí)間,過(guò)期時(shí)間要大于簽發(fā)時(shí)間
//.withIssuedAt(iatDate)//設(shè)置簽發(fā)時(shí)間
.withAudience(username) //設(shè)置 載荷 簽名的觀眾
.sign(Algorithm.HMAC256(SECRET));//加密
System.out.println("后臺(tái)生成token:" + token);
return token;
}
//校驗(yàn)TOKEN
public static boolean verifyToken(String token) throws UnsupportedEncodingException{
JWTVerifier verifier = JWT.require(Algorithm.HMAC256(SECRET)).build();
try {
verifier.verify(token);
return true;
} catch (Exception e){
return false;
}
}
//獲取Token信息
public static DecodedJWT getTokenInfo(String token) throws UnsupportedEncodingException{
JWTVerifier verifier = JWT.require(Algorithm.HMAC256(SECRET)).build();
try{
return verifier.verify(token);
} catch(Exception e){
throw new RuntimeException(e);
}
}
}
新建自定義注解:@UserLoginToken
@Target({ElementType.METHOD, ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
public @interface UserLoginToken {
boolean required() default true;
}
關(guān)于攔截器配置:
@Configuration
public class InterceptorConfig implements WebMvcConfigurer {
@Override
public void addInterceptors(InterceptorRegistry registry) {
registry.addInterceptor(authenticationInterceptor())
.addPathPatterns("/**"); // 攔截所有請(qǐng)求,通過(guò)判斷是否有 @LoginRequired 注解 決定是否需要登錄
}
@Bean
public AuthenticationInterceptor authenticationInterceptor() {
return new AuthenticationInterceptor();
}
}
public class AuthenticationInterceptor implements HandlerInterceptor {
@Autowired
UserService userService;
@Override
public boolean preHandle(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object object) throws Exception {
String token = httpServletRequest.getHeader("token");// 從 http 請(qǐng)求頭中取出 token
// 如果不是映射到方法直接通過(guò)
if(!(object instanceof HandlerMethod)){
return true;
}
HandlerMethod handlerMethod=(HandlerMethod)object;
Method method=handlerMethod.getMethod();
//檢查是否有passtoken注釋,有則跳過(guò)認(rèn)證
if (method.isAnnotationPresent(PassToken.class)) {
PassToken passToken = method.getAnnotation(PassToken.class);
if (passToken.required()) {
return true;
}
}
//檢查有沒(méi)有需要用戶權(quán)限的注解
if (method.isAnnotationPresent(UserLoginToken.class)) {
UserLoginToken userLoginToken = method.getAnnotation(UserLoginToken.class);
if (userLoginToken.required()) {
// 執(zhí)行認(rèn)證
if (token == null) {
throw new RuntimeException("無(wú)token,請(qǐng)重新登錄");
}
// 驗(yàn)證 token
if(JwtTokenUtil.verifyToken(token)){
return true;
}else {
throw new RuntimeException("401");
}
}
}
return true;
}
@Override
public void postHandle(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object o, ModelAndView modelAndView) throws Exception {
}
@Override
public void afterCompletion(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object o, Exception e) throws Exception {
}
}
登錄:
在Controller上登錄方法不用添加@UserLoginToken自定義注解,其余獲取后臺(tái)數(shù)據(jù)方法加上@UserLoginToken自定義注解,目的驗(yàn)證token是否有效,是則返回?cái)?shù)據(jù),否則提示401無(wú)權(quán)限。
測(cè)試:
@Controller
@RequestMapping(path = "/api")
public class IndexController {
private String prefix = "index/";
@GetMapping("/index")
public String index()
{
return prefix + "index";
}
@UserLoginToken
@PostMapping("/test")
@ResponseBody
public Object test(){
Map<String,Object> map = new HashMap<>();
map.put("code","200");
map.put("message","你已通過(guò)驗(yàn)證了");
return map;
}
}
HTTP請(qǐng)求帶上登陸成功后生成token,返回成功:

HTTP請(qǐng)求帶上無(wú)效token或不帶token,返回失敗:

以上就是本文的全部?jī)?nèi)容,希望對(duì)大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。
相關(guān)文章
mybatis plus代碼生成工具的實(shí)現(xiàn)代碼
這篇文章主要介紹了mybatis plus代碼生成工具的實(shí)現(xiàn)代碼,需要的朋友可以參考下2021-04-04
java密鑰交換算法DH定義與應(yīng)用實(shí)例分析
這篇文章主要介紹了java密鑰交換算法DH定義與應(yīng)用,結(jié)合實(shí)例形式分析了Java密鑰交換算法DH的原理、定義、使用方法及相關(guān)操作注意事項(xiàng),需要的朋友可以參考下2019-09-09
Java靜態(tài)代理與動(dòng)態(tài)代理案例詳解
這篇文章主要介紹了Java靜態(tài)代理與動(dòng)態(tài)代理案例詳解,本篇文章通過(guò)簡(jiǎn)要的案例,講解了該項(xiàng)技術(shù)的了解與使用,以下就是詳細(xì)內(nèi)容,需要的朋友可以參考下2021-07-07
Spring security 自定義過(guò)濾器實(shí)現(xiàn)Json參數(shù)傳遞并兼容表單參數(shù)(實(shí)例代碼)
這篇文章主要介紹了Spring security 自定義過(guò)濾器實(shí)現(xiàn)Json參數(shù)傳遞并兼容表單參數(shù),本文給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2021-01-01

