You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Spring Boot中基于学生域名的CORS跨域Token接口配置问题

动态配置CORS规则实现学生域名匹配

嗨,这个需求我之前处理过类似的,静态的@CrossOrigin(origins = "*")肯定满足不了这种按学生对应域名动态放行的要求,咱们得用动态CORS过滤器来实现,下面是具体的步骤和代码示例:

第一步:移除静态CORS注解

先把控制器上的@CrossOrigin(origins = "*")删掉,因为咱们要通过过滤器动态处理CORS规则,静态注解会和动态配置冲突。修改后的控制器接口:

@RequestMapping(value = "/getToken") 
public String provideToken() { 
    return "tokenvalue"; 
}

第二步:实现动态CORS过滤器

咱们自定义一个继承OncePerRequestFilter的过滤器,在请求进来时:

  1. 提取请求参数里的username和password
  2. 从student表查询该学生对应的domain
  3. 根据查询结果设置CORS响应头,匹配则放行,不匹配则拒绝请求

1. 数据库查询逻辑(以MyBatis为例)

先写一个Mapper接口,用来根据用户名和密码查询对应域名:

@Mapper
public interface StudentMapper {
    @Select("SELECT domain FROM student WHERE name = #{username} AND password = #{password}")
    String getDomainByUsernameAndPassword(@Param("username") String username, @Param("password") String password);
}

2. 自定义动态CORS过滤器

@Component
public class DynamicCorsFilter extends OncePerRequestFilter {

    @Autowired
    private StudentMapper studentMapper;

    @Override
    protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain) throws ServletException, IOException {
        // 提取请求参数中的用户名和密码
        String username = request.getParameter("username");
        String password = request.getParameter("password");

        String allowedDomain = null;
        // 校验参数非空后查询数据库
        if (username != null && !username.isEmpty() && password != null && !password.isEmpty()) {
            allowedDomain = studentMapper.getDomainByUsernameAndPassword(username, password);
        }

        // 处理CORS规则
        if (allowedDomain != null) {
            // 设置允许的跨域源(必须和请求的Origin完全匹配,数据库要存完整协议+域名,比如https://something.com)
            response.setHeader("Access-Control-Allow-Origin", allowedDomain);
            // 允许的请求方法
            response.setHeader("Access-Control-Allow-Methods", "GET, POST, OPTIONS");
            // 允许的请求头
            response.setHeader("Access-Control-Allow-Headers", "Content-Type, Authorization");
            // 是否允许携带凭证(比如Cookie)
            response.setHeader("Access-Control-Allow-Credentials", "true");
        } else {
            // 没有匹配到对应域名,直接返回403拒绝请求
            response.setStatus(HttpServletResponse.SC_FORBIDDEN);
            return;
        }

        // 处理浏览器的OPTIONS预检请求(跨域非简单请求会先发送OPTIONS)
        if ("OPTIONS".equals(request.getMethod())) {
            response.setStatus(HttpServletResponse.SC_OK);
            return;
        }

        // 继续执行后续请求链
        filterChain.doFilter(request, response);
    }
}

关键注意事项

  • 域名存储规范:数据库里的domain字段必须存完整的协议+域名(比如https://something.com),因为浏览器发送的Origin头是带协议的,必须完全匹配才会生效。
  • 性能优化:可以给查询结果加缓存(比如Redis或Guava Cache),避免每次请求都查数据库,尤其是用户量较大的场景。
  • 参数校验:一定要对username和password做非空校验,防止空参数导致的数据库查询异常。
  • 预检请求处理:必须正确响应OPTIONS请求,否则浏览器会拦截后续的实际请求。

内容的提问来源于stack exchange,提问作者lambad

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.21 07:39:01