过滤器手动构建响应

1.springcloud gateway 形式


import com.alibaba.fastjson.JSONObject;
import lombok.extern.slf4j.Slf4j;
import org.springframework.cloud.gateway.filter.GatewayFilterChain;
import org.springframework.cloud.gateway.filter.GlobalFilter;
import org.springframework.core.Ordered;
import org.springframework.core.io.buffer.DataBuffer;
import org.springframework.http.HttpStatus;
import org.springframework.http.server.reactive.ServerHttpResponse;
import org.springframework.stereotype.Component;
import org.springframework.web.server.ServerWebExchange;
import reactor.core.publisher.Mono;

import java.nio.charset.StandardCharsets;

/**
 */
@Component
@Slf4j
public class MdxAuthFilter implements GlobalFilter, Ordered {

    @Override
    public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
        log.info("=========================请求进入filter=========================");

        // 模拟token验证
        String token = exchange.getRequest().getHeaders().getFirst("token");
        if (!"token123".equals(token)){
            log.error("token验证失败...");
            return writeResponse(exchange.getResponse(),401,"token验证失败");
        }
        log.info("token验证成功...");
        return chain.filter(exchange);
    }

    /**
     * 值越小执行顺序越靠前
     * @return
     */
    @Override
    public int getOrder() {
        return 0;
    }

    /**
     * 构建返回内容
     *
     * @param response ServerHttpResponse
     * @param code     返回码
     * @param msg     返回数据
     * @return Mono
     */
    protected Mono<Void> writeResponse(ServerHttpResponse response, Integer code, String msg) {
        JSONObject message = new JSONObject();
        message.put("code", code);
        message.put("msg", msg);
        byte[] bits = message.toJSONString().getBytes(StandardCharsets.UTF_8);
        DataBuffer buffer = response.bufferFactory().wrap(bits);
        response.setStatusCode(HttpStatus.OK);
        // 指定编码,否则在浏览器中会中文乱码
        response.getHeaders().add("Content-Type", "application/json;charset=UTF-8");
        return response.writeWith(Mono.just(buffer));
    }
}


2.spring 单体服务过滤器直接返回

import com.alibaba.fastjson.JSONObject;
import com.pig4cloud.manage.api.entity.LoginUser;
import com.pig4cloud.manage.constant.Constants;
import com.pig4cloud.manage.constant.HttpStatus;
import com.pig4cloud.manage.constant.SecurityConstants;
import com.pig4cloud.manage.utils.*;
import com.pig4cloud.pigx.common.core.util.R;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.util.AntPathMatcher;

import javax.servlet.*;
import javax.servlet.annotation.WebFilter;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;

/**
 * token 鉴权 filter
 *
 */
//@Component 注意要使WebFilter生效,启动类需要加@ServletComponentScan注解
@WebFilter(urlPatterns = "/*", filterName = "invoiceAuthFilter")
@Slf4j
public class AuthFilter implements Filter {
    @Autowired
    private RedisClient redisService;

    private final AntPathMatcher antPathMatcher = new AntPathMatcher();
    /**
     * 不需要 鉴权的路径
     * */
    private final static String[] VALIDATE_URL = new String[]{"/login", "/code","/sendSmsCode","/v2/api-docs","/openinvoice/**","/wechat/**"};
    private final static long EXPIRE_TIME = Constants.TOKEN_EXPIRE * 60;

    @Override
    public void init(FilterConfig filterConfig) throws ServletException {
        Filter.super.init(filterConfig);
    }

    @Override
    public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
        HttpServletRequest request = (HttpServletRequest) servletRequest;
        HttpServletResponse response = (HttpServletResponse) servletResponse;
        response.setCharacterEncoding("UTF-8");

        String requestURI = request.getRequestURI();
        log.info("authFilter请求的urI===>[{}]", requestURI);
        for (String urlPattern : VALIDATE_URL) {
            if(antPathMatcher.match(urlPattern,requestURI)){
                //获取 验证码 ,登录  不需要鉴权
                filterChain.doFilter(request, response);
                return;
            }
        }

        String token = getToken(request);
//        Long userId =Long.parseLong(request.getHeader("userId"));
        if (StringUtils.isEmpty(token)) {
            unauthorizedResponse(requestURI, response, "令牌不能为空");
            return;
        }
        LoginUser userStr = redisService.get(getTokenKey(token));
        if (userStr==null) {
            unauthorizedResponse(requestURI, response, "登录状态已过期");
            return;
        }
        // 设置过期时间
        redisService.expire(getTokenKey(token), EXPIRE_TIME);
        filterChain.doFilter(request, response);
    }

    @Override
    public void destroy() {
        Filter.super.destroy();
    }

    /**
     * 获取缓存key
     */
    private String getTokenKey(String token) {
        return Constants.LOGIN_TOKEN_KEY + token;
    }

    /**
     * 获取请求token
     */
    private String getToken(HttpServletRequest request) {
        String token = request.getHeader(SecurityConstants.TOKEN_AUTHENTICATION);;
        return SecurityUtils.replaceTokenPrefix(token);
    }

    private HttpServletResponse unauthorizedResponse(String requestURI, HttpServletResponse response, String msg) throws IOException {
        response.setStatus(200);
        response.setContentType("application/json");
        response.setCharacterEncoding("utf-8");
        response.getWriter().print(JSONObject.toJSONString(R.failed(HttpStatus.UNAUTHORIZED, null, msg)));
        log.error("[鉴权异常处理]请求路径:{}", requestURI);
        return response;
    }

    public static void main(String[] args) {
        AntPathMatcher antPathMatcher = new AntPathMatcher();
        for (String url : VALIDATE_URL) {
            System.out.println(antPathMatcher.match(url,"/getDeptByPatient"));
        }
    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值