首先理解一下 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");
}
}