token令牌验证


1.在spring-mvc.xml中添加一下配置

<!-- 拦截器 -->

<mvc:interceptors>
<mvc:interceptor>
<mvc:mapping path="/cmp/*" /> <!-- 访问路径 -->
<bean class="com.core.utils.APIInterceptor" /> <!-- 拦截器所在的类 -->
</mvc:interceptor>
</mvc:interceptors>

2.创建Token实体类

/**
 * Token的Model类,可以增加字段提高安全性,例如时间戳、url签名
 * @author liuwei
 * 
 */
public class Token {

    // 用户id
    private String userId;

    // 随机生成的uuid
    private String token;

    public Token(String userId, String token) {
        this.userId = userId;
        this.token = token;
    }

    public String getUserId() {
        return userId;
    }

    public void setUserId(String userId) {
        this.userId = userId;
    }

    public String getToken() {
        return token;
    }

    public void setToken(String token) {
        this.token = token;
    }

    @Override
    public String toString() {
        return "Token [userId=" + userId + ", token=" + token + "]";
    }

}

3.创建token的service层

public interface TokenService {

    /**
     * 创建一个token关联上指定用户
     * @param userId 指定用户的id
     * @return 生成的token
     */
    public Token createToken(String userId);

    /**
     * 检查token是否有效
     * @param model token
     * @return 是否有效
     */
    public boolean checkToken(Token model);

    /**
     * 从字符串中解析token
     * @param authentication 加密后的字符串
     * @return
     */
    public Token getToken(String authentication);

}
import java.util.UUID;

import org.springframework.beans.factory.annotation.Autowired;

import org.springframework.stereotype.Service;

import com.core.bean.Token;
import com.core.service.TokenService;
import com.core.utils.Constants;
@Service
public class TokenServiceImpl implements TokenService {
    @Autowired
    private JedisClientCluster jedisClientCluster;

        public Token createToken(String userId) {
            //使用uuid作为源token
            String token = UUID.randomUUID().toString().replace("-", "");
            Token  model = new Token(userId, token);
            //加入redis缓存
            jedisClientCluster.set(userId, token);
            //jedisClientCluster.expire(userId, Constants.TOKEN_EXPIRES_SECONDS);
            
            return model;
        }

        public Token getToken(String authentication) {
            if (authentication == null || authentication.length() == 0) {
                return null;
            }
            String[] param = authentication.split("_");
            if (param.length != 2) {
                return null;
            }
            //使用userId和源token简单拼接成的token,可以增加加密措施
            String userId = param[0];
            String token = param[1];
            return new Token(userId, token);
        }

        public boolean checkToken(Token model) {
            if (model == null) {
                return false;
            }
           String token = jedisClientCluster.get(model.getUserId());
           if (token == null || !token.equals(model.getToken())) {
               return false;
           }
           // 如果验证成功,说明此用户进行了一次有效操作,延长token的过期时间
           jedisClientCluster.expire(model.getUserId(), Constants.TOKEN_EXPIRES_SECONDS);
            return true;
        }

}

 

4.创建com.core.utils.APIInterceptor类import java.lang.reflect.Method;

import java.util.UUID; import javax.annotation.Resource; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.springframework.stereotype.Component; import org.springframework.web.method.HandlerMethod; import org.springframework.web.servlet.handler.HandlerInterceptorAdapter; import com.core.annotation.Authorization; import com.core.bean.Token; import com.core.service.TokenService; @Component public class APIInterceptor extends HandlerInterceptorAdapter { private static final Log log = LogFactory.getLog(APIInterceptor.class); @Resource private TokenService tokenService; @Override 
    //拦截方法执行前,调用的方法,ture通过。false结束
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception { if (handler instanceof HandlerMethod) { HandlerMethod handlerMethod = (HandlerMethod) handler; Method method = handlerMethod.getMethod(); com.sensing.core.annotation.Token annotation = method.getAnnotation(com.sensing.core.annotation.Token.class); if (annotation != null) { boolean needSaveSession = annotation.save(); if (needSaveSession) { request.getSession(true).setAttribute("token", UUID.randomUUID().toString()); } boolean needRemoveSession = annotation.remove(); if (needRemoveSession) { if (isRepeatSubmit(request)) { log.info("please don't repeat submit,url:"+ request.getServletPath()); return false; } request.getSession(true).removeAttribute("token"); } } //从header中得到token String authorization = request.getHeader(Constants.AUTHORIZATION); if(authorization == null){ log.warn("token不存在"); response.setStatus(HttpServletResponse.SC_UNAUTHORIZED); return false; } //验证token Token model = tokenService.getToken(authorization); log.info("拦截到的token:"+model.toString()); if (tokenService.checkToken(model)) { //如果token验证成功,将token对应的用户id存在request中,便于之后注入 request.setAttribute(Constants.CURRENT_USER_ID, model.getUserId()); return true; } //如果验证token失败,并且方法注明了Authorization,返回401错误 if (method.getAnnotation(Authorization.class) != null) { response.setStatus(HttpServletResponse.SC_UNAUTHORIZED); return false; } return true; } else { return true; } }   //防止重复提交 private boolean isRepeatSubmit(HttpServletRequest request) { String serverToken = (String) request.getSession(true).getAttribute("token"); if (serverToken == null) { return true; } String clinetToken = request.getParameter("token"); if (clinetToken == null) { return true; } if (!serverToken.equals(clinetToken)) { return true; } return false; } @Override
    // 拦截方法执行后,调用的方法
public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception { System.out.println("3"); } }

 


免责声明!

本站转载的文章为个人学习借鉴使用,本站对版权不负任何法律责任。如果侵犯了您的隐私权益,请联系本站邮箱yoyou2525@163.com删除。



 
粤ICP备18138465号  © 2018-2025 CODEPRJ.COM