应明确指定可信域名白名单而非使用通配符*,启用mod_headers和mod_rewrite模块,在virtualhost中用setenvif动态设置access-control-allow-origin,并显式处理options预检请求。

在 Linux 的 Apache 中配置安全的跨域资源共享(CORS)白名单,核心是**不使用通配符 *,而是明确指定可信域名,并配合预检请求处理与响应头精细化控制**。直接写 Access-Control-Allow-Origin "*" 在生产环境属于高风险配置,应避免。
启用必要模块
确保 mod_headers 和 mod_rewrite 已启用,它们是实现安全 CORS 的基础:
- 检查是否加载:
sudo a2enmod headers rewrite(Debian/Ubuntu)或确认/etc/httpd/conf/httpd.conf中有LoadModule headers_module modules/mod_headers.so和LoadModule rewrite_module modules/mod_rewrite.so(RHEL/CentOS) - 修改后必须重启服务:
sudo systemctl restart apache2或sudo systemctl restart httpd
在 VirtualHost 中按域名白名单设置响应头
将配置写入站点对应的 <virtualhost></virtualhost>(推荐 HTTPS 环境)块内,紧邻 ServerName 下方:
- 用
Header always set替代Header set,确保错误响应(如 401、500)也携带 CORS 头,防止浏览器因缺失头而静默拦截 - 白名单示例(允许多个可信源):
<ifmodule mod_headers.c>
# 允许特定前端域名(含协议和端口)
SetEnvIf Origin "^(https?://(app\.example\.com|dashboard\.myorg\.io|localhost:3000))$" ORIGIN_IS_ALLOWED=$1
Header always set Access-Control-Allow-Origin %{ORIGIN_IS_ALLOWED}e env=ORIGIN_IS_ALLOWED
Header always set Access-Control-Allow-Credentials "true"
Header always set Access-Control-Allow-Methods "GET, POST, PUT, DELETE, OPTIONS"
Header always set Access-Control-Allow-Headers "Content-Type, Authorization, X-Requested-With"
Header append Vary Origin
</ifmodule>说明:该写法利用 SetEnvIf 匹配合法源,再通过环境变量动态注入 Access-Control-Allow-Origin 值,既满足多域名白名单,又规避了 * 与 credentials 冲突的问题。
显式处理 OPTIONS 预检请求
浏览器对带认证或自定义头的请求会先发 OPTIONS 请求。Apache 默认不响应,会导致请求挂起:
- 在同一
<virtualhost></virtualhost>块中添加:
RewriteEngine On
RewriteCond %{REQUEST_METHOD} OPTIONS
RewriteRule ^(.*)$ $1 [R=200,L]注意:若该虚拟主机同时配置了 ProxyPass(如反向代理到 Node.js 后端),这条规则必须放在 ProxyPass 指令之前,否则 OPTIONS 会被转发而非本地响应。
按路径限制 CORS 范围
不要全局开放 CORS。只对 API 接口路径启用,例如 /api/:
- 将上述
<ifmodule mod_headers.c></ifmodule>块包裹在<location></location>内 - 静态资源(JS/CSS/图片)无需 CORS 头,避免暴露额外攻击面
- 可叠加
Require all granted确保 OPTIONS 不被访问控制规则拒绝
不复杂但容易忽略











