1、安装依赖
<dependency>
<groupId>io.jsonwebtoken</groupId>
<artifactId>jjwt</artifactId>
<version>0.9.1</version>
</dependency>
当jdk版本过高时,可在依赖上方新增如下依赖
<dependency>
<groupId>javax.xml.bind</groupId>
<artifactId>jaxb-api</artifactId>
<version>2.3.0</version>
</dependency>
或者直接:
<dependency>
<groupId>com.10duke.client.jwt</groupId>
<artifactId>jjwt</artifactId>
<version>1.1.0</version>
</dependency>
2、定义token工具类
package com.example.mytest.utils.aboutResult;
import io.jsonwebtoken.*;
import lombok.extern.slf4j.Slf4j;
import java.util.Date;
import java.util.UUID;
@Slf4j
public class JwtUtil {
// private static long time=1000*60*60*24;
private static long time=1000*20;
private static String signature="admimn";
public static String createToken(String userName,String userPassword){
JwtBuilder jwtBuilder= Jwts.builder();
String jwtToken=jwtBuilder
//header
.setHeaderParam("typ","JWT")
.setHeaderParam("alg","HS256")
//payload
.claim("username",userName)
.claim("password",userPassword)
.setSubject("admin-test")
.setExpiration(new Date(System.currentTimeMillis()+time))
.setId(UUID.randomUUID().toString())
//signature
.signWith(SignatureAlgorithm.HS256,signature)
.compact();
return jwtToken;
}
public static String verify(String token) {
/**
* @desc 验证token,通过返回true
* @params [token]需要校验的串
**/
if(token==null || token==""){
return "tokenIsNull";
}
try {
Jws<Claims> claimsJws = Jwts.parser().setSigningKey(signature).parseClaimsJws(token);
} catch (ExpiredJwtException ex) {
throw new ExpiredJwtException(ex.getHeader(), ex.getClaims(), "token过期");
}
return "Success";
}
/**
* 接口解析token
* @param token
* @return
*/
public static Map<String, Object> getTokenInform(String token){
JwtParser jwtParser=Jwts.parser();
Jws<Claims> claimsJws=jwtParser.setSigningKey(signature).parseClaimsJws(token);
Claims claims=claimsJws.getBody();
Map<String,Object> result=new HashMap<>();
result.put("userName",claims.get("userName"));
result.put("userId",claims.get("userId"));
result.put("userCode",claims.get("userCode"));
result.put("role",claims.get("role"));
return result;
}
}
3、定义拦截器用于验证token
package com.example.mytest.config;
import com.example.mytest.utils.aboutResult.JwtUtil;
import io.jsonwebtoken.ExpiredJwtException;
import io.jsonwebtoken.Header;
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
@Slf4j
public class InterceptorPre implements HandlerInterceptor {
@Override
public boolean preHandle(HttpServletRequest request,
HttpServletResponse response, Object handler)
throws Exception {
String token=request.getHeader("token");
String verifyToken=JwtUtil.verify(token);
if(verifyToken=="Success"){
return true;
} else if(verifyToken=="tokenIsNull"){
throw new Exception("noToken");
} else {
return false;
}
//System.out.println("处理器前方法");
// 返回true,不会拦截后续的处理
}
@Override
public void postHandle(HttpServletRequest request,
HttpServletResponse response, Object handler,
ModelAndView modelAndView) throws Exception {
// System.out.println("处理器后方法");
log.info("处理后");
}
@Override
public void afterCompletion(HttpServletRequest request,
HttpServletResponse response, Object handler, Exception ex)
throws Exception {
log.info("处理完成");
// log.error("",ex);
//System.out.println("处理器完成方法");
}
}
4、启动类注册拦截器
package com.example.mytest;
import com.example.mytest.config.InterceptorPre;
import org.mybatis.spring.annotation.MapperScan;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.web.servlet.config.annotation.InterceptorRegistration;
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
@MapperScan("com.example.mytest.dao")
@SpringBootApplication
public class MytestApplication implements WebMvcConfigurer {
public static void main(String[] args) {
SpringApplication.run(MytestApplication.class, args);
}
//注册拦截器
@Override
public void addInterceptors(InterceptorRegistry registry){
InterceptorRegistration ir = registry.addInterceptor(new InterceptorPre());
// ir.addPathPatterns("/mytest/**");
ir.excludePathPatterns("/jwtToken/login/**");
}
}
5、定义异常处理返回结果通知
package com.example.mytest.utils.aboutResult;
import io.jsonwebtoken.ExpiredJwtException;
import lombok.extern.slf4j.Slf4j;
import org.springframework.dao.DuplicateKeyException;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.RestControllerAdvice;
@RestControllerAdvice
@Slf4j
public class IOTWebExceptionHandler {
@ExceptionHandler(value = Exception.class)
public ResultMap exceptionHandler(Exception e){
log.error("",e);
if (e instanceof DuplicateKeyException) {
return ResultMap.UNIQUE_PRIMARY_KEY.setNewErrorMsg("索引重复");
}
else if(e instanceof ClassCastException){
return ResultMap.REST_SURPASS_FREQUENCY.setNewErrorMsg("接口请求超过最大次数");
}
else if(e instanceof ExpiredJwtException){
return ResultMap.TOKEN_OVERDUE.setNewErrorMsg("token过期");
}
else {
return ResultMap.OTHER_SYSTEM_ERROR.setNewErrorMsg(e.toString());
}
}
}
6、返回值类型根据自己习惯来定义工具类