OJ在线评测系统 微服务高级 网关跨域权限校验 集中解决跨域问题 拓展 JWT校验和实现接口限流降级

微服务网关跨域权限校验

集中的去解决一下跨域

这段代码是用来配置跨源资源共享(CORS)过滤器的。它创建了一个 CorsConfiguration 实例,允许所有方法和头部,并支持凭证(如 Cookies)。setAllowedOriginPatterns 方法设置允许的源,这里用 "*" 表示允许所有来源。最后,使用 UrlBasedCorsConfigurationSource 将该配置应用于所有路径(/**),并返回一个 CorsWebFilter 实例,以便在请求时进行 CORS 处理。

复制代码
package com.yupi.yuojbackendgateway.config;

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.cors.CorsConfiguration;
import org.springframework.web.cors.reactive.CorsWebFilter;
import org.springframework.web.cors.reactive.UrlBasedCorsConfigurationSource;
import org.springframework.web.util.pattern.PathPatternParser;

import java.util.Arrays;

// 处理跨域
@Configuration
public class CorsConfig {

    @Bean
    public CorsWebFilter corsFilter() {
        CorsConfiguration config = new CorsConfiguration();
        config.addAllowedMethod("*");
        config.setAllowCredentials(true);
        // todo 实际改为线上真实域名、本地域名
        config.setAllowedOriginPatterns(Arrays.asList("*"));
        config.addAllowedHeader("*");
        UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource(new PathPatternParser());
        source.registerCorsConfiguration("/**", config);
        return new CorsWebFilter(source);
    }
}

在网关层面

自定义一个跨域的拦截器

去给请求的响应头加上一个运行跨域的注解

复制代码
package com.yupi.yuojbackendgateway.filter;

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.core.io.buffer.DataBufferFactory;
import org.springframework.http.HttpStatus;
import org.springframework.http.server.reactive.ServerHttpRequest;
import org.springframework.http.server.reactive.ServerHttpResponse;
import org.springframework.stereotype.Component;
import org.springframework.util.AntPathMatcher;
import org.springframework.web.server.ServerWebExchange;
import reactor.core.publisher.Mono;

import java.nio.charset.StandardCharsets;

@Component
public class GlobalAuthFilter implements GlobalFilter, Ordered {

    private AntPathMatcher antPathMatcher = new AntPathMatcher();

    @Override
    public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
        ServerHttpRequest serverHttpRequest = exchange.getRequest();
        String path = serverHttpRequest.getURI().getPath();
        // 判断路径中是否包含 inner,只允许内部调用
        if (antPathMatcher.match("/**/inner/**", path)) {
            ServerHttpResponse response = exchange.getResponse();
            response.setStatusCode(HttpStatus.FORBIDDEN);
            DataBufferFactory dataBufferFactory = response.bufferFactory();
            DataBuffer dataBuffer = dataBufferFactory.wrap("无权限".getBytes(StandardCharsets.UTF_8));
            return response.writeWith(Mono.just(dataBuffer));
        }
        // todo 统一权限校验,通过 JWT 获取登录用户信息
        return chain.filter(exchange);
    }

    /**
     * 优先级提到最高
     * @return
     */
    @Override
    public int getOrder() {
        return 0;
    }
}

拓展

1.JWT校验

2.可以在网关实现接口限流降级

复制代码
import io.jsonwebtoken.Claims;
import io.jsonwebtoken.Jwts;
import io.jsonwebtoken.SignatureException;

// 在类中添加JWT密钥
private static final String SECRET_KEY = "your_secret_key"; // 请替换为你的密钥

@Override
public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
    ServerHttpRequest serverHttpRequest = exchange.getRequest();
    String path = serverHttpRequest.getURI().getPath();

    // 判断路径中是否包含 inner,只允许内部调用
    if (antPathMatcher.match("/**/inner/**", path)) {
        return respondWithForbidden(exchange, "无权限");
    }

    // JWT校验逻辑
    String authorizationHeader = serverHttpRequest.getHeaders().getFirst("Authorization");
    if (authorizationHeader == null || !authorizationHeader.startsWith("Bearer ")) {
        return respondWithForbidden(exchange, "缺少或格式不正确的Authorization头");
    }

    String token = authorizationHeader.substring(7); // 移除 "Bearer " 前缀
    try {
        Claims claims = Jwts.parser()
                .setSigningKey(SECRET_KEY)
                .parseClaimsJws(token)
                .getBody();
        
        // 根据需要,您可以将用户信息提取并存储在请求的属性中
        // exchange.getAttributes().put("user", claims);
    } catch (SignatureException e) {
        return respondWithForbidden(exchange, "无效的JWT");
    } catch (Exception e) {
        return respondWithForbidden(exchange, "JWT校验失败");
    }

    return chain.filter(exchange);
}

private Mono<Void> respondWithForbidden(ServerWebExchange exchange, String message) {
    ServerHttpResponse response = exchange.getResponse();
    response.setStatusCode(HttpStatus.FORBIDDEN);
    DataBufferFactory dataBufferFactory = response.bufferFactory();
    DataBuffer dataBuffer = dataBufferFactory.wrap(message.getBytes(StandardCharsets.UTF_8));
    return response.writeWith(Mono.just(dataBuffer));
}

JWT密钥:

复制代码
private static final String SECRET_KEY = "your_secret_key"; // 请替换为你的密钥

用于签名和验证JWT的密钥。请确保此密钥保密,并使用安全的方式存储。

检查Authorization头:

复制代码
String authorizationHeader = serverHttpRequest.getHeaders().getFirst("Authorization");

获取请求头中的Authorization。

Bearer Token处理:

复制代码
if (authorizationHeader == null || !authorizationHeader.startsWith("Bearer ")) {
    return respondWithForbidden(exchange, "缺少或格式不正确的Authorization头");
}

检查头是否存在且格式正确。

JWT解析和验证:

复制代码
Claims claims = Jwts.parser()
        .setSigningKey(SECRET_KEY)
        .parseClaimsJws(token)
        .getBody();

响应处理:

复制代码
private Mono<Void> respondWithForbidden(ServerWebExchange exchange, String message) {
    ...
}

抽取出的响应处理方法,方便在需要时发送403响应。

请确保JWT的签名和解析使用相同的密钥。

根据实际需要处理用户信息和权限。

思考:

企业级开发真的有必要用微服务吗

真的有必要用 Spring Cloud 实现微服务吗

大多数情况下 一般使用API RPC HTTP 实现跨部门 服务的实现

各部门直接共享一套接口的定义

数据格式 和 调用代码全部自动生成 保持统一 同时解耦

相关推荐
知行EDI6 小时前
知行之桥 MaBang 端口使用指南——Create Order 订单创建篇
java·服务器·数据库
笑鸿的学习笔记6 小时前
C++笔记之大块顺序写
java·c++·笔记
打工仔折腾 AI6 小时前
从 Demo 到生产级 Agent:8 个关键设计机制与 Python 实现拆解
java·jvm·人工智能·后端·python·langchain·ai agent 实战
殷色玫瑰7 小时前
C/C++ 内存管理详解:从内存分布到 new/delete 底层原理
java·linux·c语言·c++
code_slave(码畜)8 小时前
微服务架构落地:基础服务 —— 报表服务(中篇:元数据、查询引擎、缓存与权限落地)
spring boot·spring cloud·缓存·微服务·架构
豆豆8 小时前
2026 年建站架构选型实录:从 SC-081v3 证书新政与备案新规倒推 CMS 选型口径
架构·https·cms·geo·acme·web架构·pageadmin
知识分享小能手8 小时前
C++ 学习教程,从入门到精通,C++ 友元、异常和其他特性 — 详细知识点(15)
开发语言·c++·学习
海宇大数据9 小时前
零信任架构实战:基于海宇活体识别V步骤1构建自动化远程公证会话初始化网关
运维·人工智能·架构·自动化
邵奈一9 小时前
Codex 重连卡半天,一行配置搞定
架构
青山木9 小时前
Hot 100 --- 编辑距离
java·数据结构·算法·leetcode·动态规划