|  | @@ -0,0 +1,170 @@
 | 
	
		
			
				|  |  | +package com.xunmei.deploy.interceptor;
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +import com.alibaba.fastjson.JSON;
 | 
	
		
			
				|  |  | +import com.xunmei.common.core.utils.StringUtils;
 | 
	
		
			
				|  |  | +import com.xunmei.deploy.dao.HostInfoDao;
 | 
	
		
			
				|  |  | +import com.xunmei.deploy.domain.HostInfo;
 | 
	
		
			
				|  |  | +import com.xunmei.deploy.util.RedisPrefix;
 | 
	
		
			
				|  |  | +import com.xunmei.deploy.util.RedisTemplateUtil;
 | 
	
		
			
				|  |  | +import com.xunmei.deploy.vo.TokenCache;
 | 
	
		
			
				|  |  | +import org.slf4j.Logger;
 | 
	
		
			
				|  |  | +import org.slf4j.LoggerFactory;
 | 
	
		
			
				|  |  | +import org.springframework.beans.factory.annotation.Autowired;
 | 
	
		
			
				|  |  | +import org.springframework.stereotype.Component;
 | 
	
		
			
				|  |  | +import org.springframework.stereotype.Controller;
 | 
	
		
			
				|  |  | +import org.springframework.web.servlet.AsyncHandlerInterceptor;
 | 
	
		
			
				|  |  | +import org.springframework.web.servlet.handler.HandlerInterceptorAdapter;
 | 
	
		
			
				|  |  | +import javax.annotation.Resource;
 | 
	
		
			
				|  |  | +import javax.servlet.http.HttpServletRequest;
 | 
	
		
			
				|  |  | +import javax.servlet.http.HttpServletResponse;
 | 
	
		
			
				|  |  | +import java.io.PrintWriter;
 | 
	
		
			
				|  |  | +import java.util.HashMap;
 | 
	
		
			
				|  |  | +import java.util.Map;
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +/**
 | 
	
		
			
				|  |  | + * 令牌验证拦截器
 | 
	
		
			
				|  |  | + */
 | 
	
		
			
				|  |  | +@Controller
 | 
	
		
			
				|  |  | +@Component
 | 
	
		
			
				|  |  | +public class TokenInterceptor implements AsyncHandlerInterceptor {
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +    private static final long TIME_MAX = 2 * 60 * 60;
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +    private Logger log = LoggerFactory.getLogger(getClass());
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +    @Autowired
 | 
	
		
			
				|  |  | +    private HostInfoDao hostInfoDao;
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +    @Resource
 | 
	
		
			
				|  |  | +    private RedisTemplateUtil redisTemplateUtil;
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +    @Override
 | 
	
		
			
				|  |  | +    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
 | 
	
		
			
				|  |  | +        //获取请求中的token
 | 
	
		
			
				|  |  | +        String token = request.getHeader("Authorization");
 | 
	
		
			
				|  |  | +        //todo:
 | 
	
		
			
				|  |  | +        //判断url是否需要进行拦截
 | 
	
		
			
				|  |  | +        String basePath = request.getContextPath();
 | 
	
		
			
				|  |  | +        String path = request.getRequestURI();
 | 
	
		
			
				|  |  | +        if(!validateInterceptor(path,basePath)){
 | 
	
		
			
				|  |  | +            return true;
 | 
	
		
			
				|  |  | +        }
 | 
	
		
			
				|  |  | +        /*if(request.getSession().getAttribute("userId") == null){
 | 
	
		
			
				|  |  | +            log.error("请求:{},没有用户ID!",path);
 | 
	
		
			
				|  |  | +            return false;
 | 
	
		
			
				|  |  | +        }*/
 | 
	
		
			
				|  |  | +        response.setCharacterEncoding("UTF-8");
 | 
	
		
			
				|  |  | +        response.setContentType("application/json;charset=utf-8");
 | 
	
		
			
				|  |  | +        //验证消息头是否有token
 | 
	
		
			
				|  |  | +        if(StringUtils.isEmpty(token)){
 | 
	
		
			
				|  |  | +            log.error("请求:{},未携带令牌!",path);
 | 
	
		
			
				|  |  | +            response.setStatus(401);
 | 
	
		
			
				|  |  | +            PrintWriter writer = response.getWriter();
 | 
	
		
			
				|  |  | +            Map<String,Object> map = new HashMap<>();
 | 
	
		
			
				|  |  | +            map. put("message","无效的秘钥");
 | 
	
		
			
				|  |  | +            writer.println(JSON.toJSONString(map));
 | 
	
		
			
				|  |  | +            return false;
 | 
	
		
			
				|  |  | +        }
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +        token = StringUtils.replace(token,"Bearer ","");
 | 
	
		
			
				|  |  | +        //验证该token是否在系统中存在
 | 
	
		
			
				|  |  | +        TokenCache tokenCache = null;
 | 
	
		
			
				|  |  | +        String result = redisTemplateUtil.get(RedisPrefix.CACHE_TOKEN_TIMES + ":" + token);
 | 
	
		
			
				|  |  | +        if (org.apache.commons.lang3.StringUtils.isNotBlank(result)){
 | 
	
		
			
				|  |  | +            tokenCache =  JSON.parseObject(result, TokenCache.class);
 | 
	
		
			
				|  |  | +        }
 | 
	
		
			
				|  |  | +        if(tokenCache == null){
 | 
	
		
			
				|  |  | +            log.error("请求:{},令牌在中心不存在!",path);
 | 
	
		
			
				|  |  | +            response.setStatus(401);
 | 
	
		
			
				|  |  | +            PrintWriter writer = response.getWriter();
 | 
	
		
			
				|  |  | +            Map<String,Object> map = new HashMap<>();
 | 
	
		
			
				|  |  | +            map.put("message","无效的秘钥");
 | 
	
		
			
				|  |  | +            writer.println(JSON.toJSONString(map));
 | 
	
		
			
				|  |  | +            return false;
 | 
	
		
			
				|  |  | +        }
 | 
	
		
			
				|  |  | +        Long timp = tokenCache.getTokenDate();
 | 
	
		
			
				|  |  | +        if(timp == null){
 | 
	
		
			
				|  |  | +            log.error("请求:{},令牌无效!",path);
 | 
	
		
			
				|  |  | +            response.setStatus(401);
 | 
	
		
			
				|  |  | +            PrintWriter writer = response.getWriter();
 | 
	
		
			
				|  |  | +            Map<String,Object> map = new HashMap<>();
 | 
	
		
			
				|  |  | +            map.put("message","无效的秘钥");
 | 
	
		
			
				|  |  | +            writer.println(JSON.toJSONString(map));
 | 
	
		
			
				|  |  | +            return false;
 | 
	
		
			
				|  |  | +        }
 | 
	
		
			
				|  |  | +        //当前时间戳
 | 
	
		
			
				|  |  | +        long now = System.currentTimeMillis();
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +        //验证token时间是否过期
 | 
	
		
			
				|  |  | +        long timeDiff = (now - timp) / 1000;
 | 
	
		
			
				|  |  | +        //令牌时间过期
 | 
	
		
			
				|  |  | +        if(timeDiff > TIME_MAX){
 | 
	
		
			
				|  |  | +            log.error("请求:{},令牌超时!",path);
 | 
	
		
			
				|  |  | +            response.setStatus(401);
 | 
	
		
			
				|  |  | +            PrintWriter writer = response.getWriter();
 | 
	
		
			
				|  |  | +            Map<String,Object> map = new HashMap<>();
 | 
	
		
			
				|  |  | +            map. put("message","无效的秘钥");
 | 
	
		
			
				|  |  | +            writer.println(JSON.toJSONString(map));
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +            //过期清除缓存,清除数据库令牌和令牌时间
 | 
	
		
			
				|  |  | +            redisTemplateUtil.del(RedisPrefix.CACHE_TOKEN_TIMES + ":" + token);
 | 
	
		
			
				|  |  | +            String clientId = tokenCache.getClientId();
 | 
	
		
			
				|  |  | +            HostInfo hostInfo = hostInfoDao.selectById(clientId);
 | 
	
		
			
				|  |  | +            hostInfo.setTokenCreateTime(null);
 | 
	
		
			
				|  |  | +            hostInfo.setAccessToken(null);
 | 
	
		
			
				|  |  | +            hostInfoDao.updateById(hostInfo);
 | 
	
		
			
				|  |  | +            return false;
 | 
	
		
			
				|  |  | +        }
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +        return true;
 | 
	
		
			
				|  |  | +    }
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +    /***
 | 
	
		
			
				|  |  | +     * @Author gaoxiong
 | 
	
		
			
				|  |  | +     * @Description 路径是否需要被拦截
 | 
	
		
			
				|  |  | +     * @Date 9:58 2021/4/14
 | 
	
		
			
				|  |  | +     * @Param
 | 
	
		
			
				|  |  | +     * @param path
 | 
	
		
			
				|  |  | +     * @param basePath
 | 
	
		
			
				|  |  | +     * @return boolean
 | 
	
		
			
				|  |  | +     **/
 | 
	
		
			
				|  |  | +    private boolean validateInterceptor(String path,String basePath){
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +        path = path.substring(basePath.length());
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +/*        if(path.contains("static")){
 | 
	
		
			
				|  |  | +            return false;
 | 
	
		
			
				|  |  | +        }*/
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +        if(path.contains("/api/deploy/register")){
 | 
	
		
			
				|  |  | +            return false;
 | 
	
		
			
				|  |  | +        }
 | 
	
		
			
				|  |  | +        if(path.contains("/api/deploy/accesstoken")){
 | 
	
		
			
				|  |  | +            return false;
 | 
	
		
			
				|  |  | +        }
 | 
	
		
			
				|  |  | +        if(path.contains("/api/deploy/package/download")){
 | 
	
		
			
				|  |  | +            return false;
 | 
	
		
			
				|  |  | +        }
 | 
	
		
			
				|  |  | +        if(path.contains("/api/deploy/frontend/synchronDate")){
 | 
	
		
			
				|  |  | +            return false;
 | 
	
		
			
				|  |  | +        }
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +        if(path.contains("api/deploy/")){
 | 
	
		
			
				|  |  | +            return true;
 | 
	
		
			
				|  |  | +        }
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +        if(path.contains("/DeployPage")){
 | 
	
		
			
				|  |  | +            return false;
 | 
	
		
			
				|  |  | +        }
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +        if(path.contains("/deployData")){
 | 
	
		
			
				|  |  | +            return false;
 | 
	
		
			
				|  |  | +        }
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +        return false;
 | 
	
		
			
				|  |  | +    }
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +}
 |