springcloud zuul 请求过滤 前端拿不到http状态码,报跨域问题

最近一个项目使用到了springcloud zuul 使用了jwt token认证,认证不通过返给前端401的状态码,但是折腾了半天,找了很多东西,前端(VUE)死活拿不到状态码,一直在报跨域的错误,结果还是针对跨域的问题,修改了一下代码,前端就能拿到了。

package com.filter;

import com.ftes_common.Service.JwtTokenService;
import com.ftes_common.constant.Constant;
import com.ftes_common.constant.ResultMessage;
import com.ftes_common.model.ResultObjectC;
import com.ftes_common.plugin.jgrid.JsonUtils;
import com.ftes_common.utils.Md5Util;
import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
import com.netflix.zuul.ZuulFilter;
import com.netflix.zuul.context.RequestContext;
import com.sun.org.apache.bcel.internal.generic.NEW;
import net.sf.json.JSONObject;
import net.sf.json.JSONString;
import org.apache.logging.log4j.util.Strings;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.json.GsonJsonParser;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Component;
import org.springframework.web.util.WebUtils;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.Map;

@Component
public class AuthFilter extends ZuulFilter {
    private static String[] urls = null;

    static {
        urls = new String[]{"/base/sysLogin"}; // 	需要过滤的请求
    }

    @Autowired
    JwtTokenService jwtTokenService;
    @Autowired
    StringRedisTemplate stringRedisTemplate;


    @Override
    public Object run() {
        RequestContext ctx = RequestContext.getCurrentContext();
        HttpServletRequest request = ctx.getRequest();
        ctx.getResponse().setContentType("text/html;charset=utf-8"); // 中文乱码
        ResultObjectC res = null;
        String token = request.getHeader(Constant.TOKEN_HEADER);
        String requestURI = request.getRequestURI();
        // 过滤特殊请求
        for (String url : urls) {
            if (url.equals(requestURI)) {
                ctx.setSendZuulResponse(true); // 对该请求进行路由
                ctx.setResponseStatusCode(200);
                return null;
            }
        }
        if (request.getMethod().equals("OPTIONS")) {
            ctx.setSendZuulResponse(true);
            ctx.setResponseStatusCode(200);
            return null;
        }
        // token 认证
        if (Strings.isBlank(token)) {
            ctx.setSendZuulResponse(false); // 过滤该请求,不对其进行路由
            ctx.setResponseStatusCode(HttpStatus.UNAUTHORIZED.value());
            //  针对跨域拿不到返回值的情况 
            ctx.addZuulResponseHeader("Access-Control-Allow-Origin","*");
            res = new ResultObjectC();
            res.setCode(401);
            res.setMessage(ResultMessage.TOKEN_IS_EMPTY);
            ctx.setResponseBody(com.alibaba.fastjson.JSONObject.toJSONString(res));
            return null;
        } else {
            Map data = null;
            try {
                data = jwtTokenService.verifyToken(token);
            } catch (Exception e) {
                ctx.setSendZuulResponse(false);
                 ctx.setResponseStatusCode(HttpStatus.UNAUTHORIZED.value());
                ctx.addZuulResponseHeader("Access-Control-Allow-Origin","*");

                res = new ResultObjectC();
                res.setCode(401);
                res.setMessage(ResultMessage.TOKEN_NOT_AVAILABLE);
                ctx.setResponseBody(com.alibaba.fastjson.JSONObject.toJSONString(res));
                return null;
            }
            if (data != null) {
                // 当前用户是否在其他地方登录认证
                //  Map map = claims.get(Constant.USER_DATA_MAP, Map.class);
                String accId = (String) data.get(Constant.ACCID);
                String redisToken = stringRedisTemplate.opsForValue().get(accId);
                if (!token.equals(redisToken)) {

                    ctx.setSendZuulResponse(false);
                    ctx.setResponseStatusCode(HttpStatus.UNAUTHORIZED.value());
                    ctx.addZuulResponseHeader("Access-Control-Allow-Origin","*");
                    res = new ResultObjectC();
                    res.setCode(401);
                    res.setMessage(ResultMessage.DUPL_O_LOGIN);
                    ctx.setResponseBody(com.alibaba.fastjson.JSONObject.toJSONString(res));

                    return null;
                } else {
                    ctx.setSendZuulResponse(true); // 对该请求进行路由
                    ctx.setResponseStatusCode(200);
                    return null;
                }

            } else {
                ctx.setSendZuulResponse(false);
                ctx.setResponseStatusCode(HttpStatus.UNAUTHORIZED.value());
                ctx.addZuulResponseHeader("Access-Control-Allow-Origin","*");

                res = new ResultObjectC();
                res.setCode(401);
                res.setMessage(ResultMessage.TOKEN_NOT_AVAILABLE);
                ctx.setResponseBody(com.alibaba.fastjson.JSONObject.toJSONString(res));
                return null;
            }


        }

    }

    @Override
    public boolean shouldFilter() {
        return true;// 是否执行该过滤器,此处为true,说明需要过滤
    }

    @Override
    public int filterOrder() {
        return 0;// 优先级为0,数字越大,优先级越低
    }

    @Override
    public String filterType() {
        return "pre";// 前置过滤器  定义filter的类型,有pre、route、post、error四种
    }
}  

前端请求响应拦截器:

/**响应拦截器:登录过期,返回登录页*/
http.interceptors.response.use(function (response) {
    //console.log(response);
    // loadingInstance.close();
    return response
}, error => {
    Promise.reject(error);
    // loadingInstance.close();
    Message({showClose: true, message: '请求出错!', type: 'error'});
});

如果 请求被拦截使用 ctx.setResponseStatusCode(HttpStatus.UNAUTHORIZED.value()); 前端拿不到值,可以尝试换成 ctx.setResponseStatusCode(HttpStatus.OK.value());

你可能感兴趣的:(bug)