首先理解一下 session 與 token
session
當用戶第一次通過瀏覽器使用用戶名和密碼訪問服務器時,服務器會驗證用戶數據,驗證成功后在服務器端寫入session數據,
向客戶端瀏覽器返回sessionid,瀏覽器將sessionid保存在cookie中,當用戶再次訪問服務器時,會攜帶
sessionid,服務器會拿着sessionid從數據庫獲取session數據,然后進行用戶信息查詢,查詢到,就會將查詢到的用戶信息返回,
從而實現狀態保持,通常session是存儲在內存中的,每個用戶通過認證之后都會將session數據保存在服務器的內存中,而當用戶量增大時,服務器的壓力增大。
token
而token在服務器是可以不需要存儲用戶的信息的
-------------------------------------------代碼 ---------------------------------------------
public class TokenUtil {
// 秘鑰自己定義
private static final String SECRET = "f1034b4e2f5241b497fd643d35c9a918";
// iss (issuer):簽發人
//
// exp (expiration time):過期時間
//
// sub (subject):主題
//
// aud (audience):受眾
//
// nbf (Not Before):生效時間
//
// iat (Issued At):簽發時間
//
// jti (JWT ID):編號
private static Key generatorKey(){
SignatureAlgorithm hs256 = SignatureAlgorithm.HS256;
byte[] baa = DatatypeConverter.
parseBase64Binary("f1034b4e2f5241b497fd643d35c9a918");
return new SecretKeySpec(baa,hs256.getJcaName());
}
public static String genertorToken(Map<String,Object> payload ){
ObjectMapper objectMapper = new ObjectMapper();
try {
return Jwts.builder().setPayload(objectMapper.writeValueAsString(payload))
.signWith(SignatureAlgorithm.HS256,generatorKey()).compact();
} catch (JsonProcessingException e) {
e.printStackTrace();
}
return null;
}
public static Claims phaseToken(String token) {
Jws<Claims> claimsJws = Jwts.parser().
setSigningKey(generatorKey()).
parseClaimsJws(token);
return claimsJws.getBody();
}
}
==============================================
1 設置過期時間 主要信息字段 生成token
2 校驗 token
==============================================
攔截器配置
1 手寫 匿名類
@Target({ElementType.METHOD, ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)// 運行時有效
public @interface IgnoreAuth {
}
2 extends HandlerInterceptorAdapter
@Component
public class HCInterceptor extends HandlerInterceptorAdapter {
private final String ACCESS_TOKEN = "access_token";
@Autowired
private LoginService service;
@Override
public boolean preHandle(HttpServletRequest request,
HttpServletResponse response,
Object handler) throws Exception {
HandlerMethod handlerMethod =(HandlerMethod)handler;
Object bean = handlerMethod.getBean();
if(!(bean instanceof BaseController)){
return false ;
}
if(isAnoyous(handlerMethod)){
return true ;
}
String token = CookUtil.getCookieValue(request, ACCESS_TOKEN);
if(StringUtils.isEmpty(token)){
if(CookUtil.isAjaxRequest(request)){
response.getWriter().write("{'code':-1;'mag':error}");
return false;
}
response.sendRedirect("login.html");
return false;
}
CheckRequest request1 = new CheckRequest();
request1.setToken(token);
CheckResponse response1 = service.vialdToken(request1);
if("000000".equals(response1.getCode())){
BaseController baseController = (BaseController)bean;
baseController.setUid(response1.getuId());
return true;
}
ObjectMapper objectMapper = new ObjectMapper();
response.getWriter().write("{'code':-1;'mag':token驗證失敗!}");
return false;
}
private boolean isAnoyous(HandlerMethod handlerMethod){
Object bean = handlerMethod.getBean();
Class clazz = bean.getClass();
if(clazz.getAnnotation(IgnoreAuth.class) != null){
return true ;
}
Method method = handlerMethod.getMethod();
return method.getAnnotation(IgnoreAuth.class) != null ;
}
3 將攔截器注入到web中
@Configuration
public class InterceptorConfig implements WebMvcConfigurer {
@Override
public void addInterceptors(InterceptorRegistry registry) {
registry.addInterceptor(new HCInterceptor())
.addPathPatterns("/")
.excludePathPatterns("/resources/")
.excludePathPatterns("/js/**")
.excludePathPatterns("/")
.excludePathPatterns("/error")
.excludePathPatterns("/index")
.excludePathPatterns("/home")
.excludePathPatterns("/login");
}
}