最近项目中需要做每一个接口均加token参数,web端进行验证。
我实用的是拦截器。
1、整体思路是定义好需要拦截的路径,并将使用的接口添加@ApiToken
2、符合路径并且添加了注解的接口发送请求时会进入拦截器,拦截器负责比对传入的token是否正确(暂未加密处理);
3、正确则继续,否则直接返回JSON。
1.Configuration
import cn.ac.bcc.ebap.common.interceptor.WebApiInterceptor;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter;
@Configuration
public class AppTockenConfiguration extends WebMvcConfigurerAdapter {
@Bean
public WebApiInterceptor webApiInterceptor(){
return new WebApiInterceptor ();
}
@Override
public void addInterceptors(InterceptorRegistry registry){
//多个拦截器组成一个拦截器链
//addPathPattern 用于添加拦截规则 路径,是带api接口的
//用于定义、排除用户的拦截
registry.addInterceptor(webApiInterceptor())
.addPathPatterns("/a/depart/**");
// .excludePathPatterns("/a/login");
super.addInterceptors(registry);
}
}
2.WebApiInterceptor
这边返回值直接返回JSON。
import cn.ac.bcc.ebap.common.annotation.ApiToken;
import com.alibaba.fastjson.JSONObject;
import org.apache.log4j.Logger;
import org.springframework.web.method.HandlerMethod;
import org.springframework.web.servlet.ModelAndView;
import org.springframework.web.servlet.handler.HandlerInterceptorAdapter;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.PrintWriter;
import java.lang.reflect.Method;
public class WebApiInterceptor extends HandlerInterceptorAdapter {
private static final Logger log = Logger.getLogger(WebApiInterceptor.class);
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler)
throws Exception {
if (!(handler instanceof HandlerMethod)) {
return true;
}
HandlerMethod handlerMethod = (HandlerMethod) handler;
Method method = handlerMethod.getMethod();
String sessionId = request.getSession ().getId ();
if(sessionId == null){
log.info("sessionId 已失效");
// throw new RuntimeException ();
response.setCharacterEncoding("UTF-8");
response.setContentType("application/json; charset=utf-8");
PrintWriter out = null ;
JSONObject res = new JSONObject ();
res.put("resultCode",302);
res.put("message","sessionId 已失效");
out = response.getWriter();
out.append(res.toString());
return false;
}
String token = request.getParameter ("access_token");
log.info("Token:{" + token + "}; 请求路径:{" + request.getRequestURI() + "}");
if (method.isAnnotationPresent(ApiToken.class)) {
if (token != null) {
if(token.equals (sessionId)){
return true;
}else{
log.info("token不可用");
// throw new RuntimeException ();
response.setCharacterEncoding("UTF-8");
response.setContentType("application/json; charset=utf-8");
PrintWriter out = null ;
JSONObject res = new JSONObject ();
res.put("code",300);
res.put("message","token不可用");
out = response.getWriter();
out.append(res.toString());
return false;
}
}else{
log.info("token不可为空");
// throw new RuntimeException ();
response.setCharacterEncoding("UTF-8");
response.setContentType("application/json; charset=utf-8");
PrintWriter out = null ;
JSONObject res = new JSONObject ();
res.put("code",301);
res.put("message","token不可为空");
out = response.getWriter();
out.append(res.toString());
return false;
}
}
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 {
System.out.println("========方法执行之后 开始调用===============");
}
}
3. 注解
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
/**
* Created by zhanghaipeng on 2020/3/30.
*/
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface ApiToken {
}
ps:可以模拟JWT进一步优化,如加入过期时间参数等。