小伙伴在系统开发过程中,会遇到部分接口需要授权才能请求的问题,通常的做法是服务端在客户端登录成功后 ,按一定规则生成token,返回给客户端。然后客户端在请求需要授权的接口时,带上此token。那么问题来了,服务端如何对token做统一的校验?
方法一:过滤器或者拦截器
利用过滤器实现,放掉不需要校验的接口,然后校验剩余接口的token.
此方法配置略显复杂,静态资源什么的也需要配置,比较麻烦。
方法二: 自定义注解校验token
1.创建自定义注解
package com.huizhongcf.cloud.api.interceptor;
import java.lang.annotation.Documented;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
@Target(ElementType.METHOD)//这个注解是应用在方法上
@Retention(RetentionPolicy.RUNTIME)//注解会在class中存在,运行时可通过反射获取
@Documented
public @interface AppToken {
}
- 配置拦截器
package com.huizhongcf.cloud.api.interceptor;
import java.io.IOException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.apache.log4j.Logger;
import org.codehaus.jackson.JsonGenerationException;
import org.codehaus.jackson.map.JsonMappingException;
import org.codehaus.jackson.map.ObjectMapper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.method.HandlerMethod;
import org.springframework.web.servlet.handler.HandlerInterceptorAdapter;
import com.huizhongcf.constant.CustomerConstant;
import com.huizhongcf.util.JedisClientUtil;
import com.huizhongcf.util.StringUtil;
import com.huizhongcf.vo.AppReturnMsgData;
@Configuration
public class AppTokenInterceptor extends HandlerInterceptorAdapter{
private static final Logger logger = Logger .getLogger(AppTokenInterceptor.class);
@Autowired
JedisClientUtil jedisClientUtil;
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
if (handler.getClass().isAssignableFrom(HandlerMethod.class)) {
AppToken authentication = ((HandlerMethod) handler)
.getMethodAnnotation(AppToken.class);
// 没有声明需要权限,或者声明不验证权限
if (authentication == null
|| authentication.validate() == false) {
return true;
} else {
String token = request.getHeader("token");
logger.debug("current token**************: " + token);
if (StringUtil.isBlank(token)) {
returnValue(response);
return false;
} else {
if (!jedisClientUtil.exists(token)) {
returnValue(response);
return false;
}
logger.debug("You have logged in successfully!");
//延长token过期时间
jedisClientUtil.expire(token, CustomerConstant.REDIS_TOKEN_DELAY);
return true;
}
}
} else {
return true;
}
}
private void returnValue(HttpServletResponse response)
throws JsonGenerationException, JsonMappingException, IOException {
AppReturnMsgData retMsgData = new AppReturnMsgData("1000", "登录超时");
ObjectMapper mapper = new ObjectMapper();
response.setCharacterEncoding("UTF-8");
response.setContentType("application/json; charset=utf-8");
response.getWriter().write(mapper.writeValueAsString(retMsgData));
}
}
3.spring mvc配置
<mvc:interceptors>
<bean class = "com.huizhongcf.cloud.api.interceptor.AppTokenInterceptor" />
</mvc:interceptors >