本文目录导读:

PHP项目跨域配置的安全设置需要谨慎操作,以下是最佳实践:
基础安全配置
通用配置示例
// 设置允许的域名白名单
$allowed_origins = [
'https://yourdomain.com',
'https://app.yourdomain.com'
];
$origin = $_SERVER['HTTP_ORIGIN'] ?? '';
if (in_array($origin, $allowed_origins)) {
header("Access-Control-Allow-Origin: $origin");
header("Access-Control-Allow-Credentials: true");
}
框架配置示例
Laravel
// config/cors.php
return [
'paths' => ['api/*'],
'allowed_methods' => ['GET', 'POST', 'PUT', 'DELETE'],
'allowed_origins' => [
'https://frontend.com',
'https://admin.frontend.com'
],
'allowed_headers' => [
'Content-Type',
'X-Requested-With',
'Authorization'
],
'exposed_headers' => ['X-Total-Count'],
'max_age' => 3600,
'supports_credentials' => true,
];
Symfony
// config/packages/nelmio_cors.yaml
nelmio_cors:
defaults:
allow_origin: ['%cors_allow_origin%']
allow_methods: ['GET', 'OPTIONS', 'POST', 'PUT', 'DELETE']
allow_headers: ['Content-Type', 'Authorization']
max_age: 3600
paths:
'^/api/':
allow_origin: ['https://allowed-domain.com']
allow_credentials: true
关键安全措施
禁止通配符配置
// ❌ 不安全 - 不要使用
header("Access-Control-Allow-Origin: *");
// ✅ 安全 - 指定具体域名
header("Access-Control-Allow-Origin: https://specific-domain.com");
限制HTTP方法
// 只允许必要的方法
header("Access-Control-Allow-Methods: GET, POST, PUT, DELETE");
// 不要开放OPTIONS以外的其他方法
控制预检请求缓存
// 减少OPTIONS请求频率
header("Access-Control-Max-Age: 86400"); // 24小时
动态验证配置
class CorsMiddleware {
private $allowedOrigins = [
'https://production.com',
'https://staging.com'
];
public function handle($request) {
$origin = $request->header('Origin');
// 严格验证来源
if ($origin && !$this->isValidOrigin($origin)) {
return response('Forbidden', 403);
}
// 方法验证
if ($request->isMethod('OPTIONS')) {
return $this->handlePreflight($origin);
}
// 设置CORS头
if ($origin) {
header("Access-Control-Allow-Origin: $origin");
}
return true;
}
private function isValidOrigin($origin) {
// 验证域名格式
$parsed = parse_url($origin);
if (!isset($parsed['host'])) {
return false;
}
// 白名单检查
return in_array($parsed['host'], $this->allowedOrigins);
}
}
敏感操作的安全配置
带认证的请求
// 需要认证的API端点
header("Access-Control-Allow-Credentials: true");
header("Access-Control-Allow-Origin: https://trusted-domain.com");
header("Access-Control-Allow-Headers: Authorization, Content-Type");
// 额外的安全头
header("X-Content-Type-Options: nosniff");
header("X-Frame-Options: DENY");
处理复杂请求
// 预检请求处理
if ($_SERVER['REQUEST_METHOD'] === 'OPTIONS') {
// 验证来源
$origin = $_SERVER['HTTP_ORIGIN'] ?? '';
if (!in_array($origin, $allowedOrigins)) {
http_response_code(403);
exit;
}
// 验证请求方法
$method = $_SERVER['HTTP_ACCESS_CONTROL_REQUEST_METHOD'] ?? '';
if (!in_array($method, ['GET', 'POST', 'PUT', 'DELETE'])) {
http_response_code(403);
exit;
}
// 验证请求头
$headers = $_SERVER['HTTP_ACCESS_CONTROL_REQUEST_HEADERS'] ?? '';
// 只允许必要的请求头
http_response_code(204);
exit;
}
最佳实践总结
配置文件示例
<?php
// cors_config.php
return [
// 白名单
'allowed_origins' => [
'https://app.myproject.com',
'https://admin.myproject.com'
],
// 允许的方法
'allowed_methods' => ['GET', 'POST', 'PUT', 'DELETE', 'OPTIONS'],
// 允许的请求头
'allowed_headers' => [
'Content-Type',
'Authorization',
'X-Requested-With'
],
// 暴露的响应头
'exposed_headers' => [
'X-Total-Count',
'X-Pagination-Pages'
],
// 预检请求缓存时间(秒)
'max_age' => 86400,
// 是否允许凭证
'supports_credentials' => true,
// 安全头
'security_headers' => [
'X-Content-Type-Options' => 'nosniff',
'X-Frame-Options' => 'DENY',
'X-XSS-Protection' => '1; mode=block'
]
];
安全注意事项
避免的操作
// ❌ 不要这样做
header("Access-Control-Allow-Origin: *");
header("Access-Control-Allow-Methods: *");
header("Access-Control-Allow-Headers: *");
// ❌ 不要信任所有来源
$origin = $_SERVER['HTTP_ORIGIN'] ?? '';
header("Access-Control-Allow-Origin: $origin");
生产环境检查清单
- [ ] 使用明确的白名单,而非通配符
- [ ] 限制允许的HTTP方法
- [ ] 验证Origin头格式
- [ ] 启用CSRF防护
- [ ] 使用HTTPS
- [ ] 限制暴露的响应头
- [ ] 设置合理的预检请求缓存时间
- [ ] 记录跨域请求日志
- [ ] 定期更新依赖
这些配置能有效防止CSRF攻击和未授权访问,同时确保合法跨域请求的正常运行。