From 5e73dc6ec15b8483e3eec11aa59435e3bd9b2bf2 Mon Sep 17 00:00:00 2001 From: kang Date: Thu, 28 May 2026 10:11:54 +0800 Subject: [PATCH] =?UTF-8?q?feat:=20=E6=B7=BB=E5=8A=A0=20CORS=20=E9=85=8D?= =?UTF-8?q?=E7=BD=AE=E9=80=89=E9=A1=B9=E8=87=B3=20.env.example=20=E6=96=87?= =?UTF-8?q?=E4=BB=B6?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 新增 CORS_ALLOWED_ORIGINS 和 CORS_ALLOWED_ORIGINS_PATTERNS 以支持跨域请求的来源白名单配置。 - 添加 CORS_MAX_AGE 和 CORS_SUPPORTS_CREDENTIALS 选项,增强跨域请求的灵活性与安全性。 --- .env.example | 16 +++++++++ config/cors.php | 87 +++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 103 insertions(+) create mode 100644 config/cors.php diff --git a/.env.example b/.env.example index c38c119..3d953aa 100644 --- a/.env.example +++ b/.env.example @@ -40,6 +40,22 @@ APP_MAINTENANCE_DRIVER=file # 内置 PHP 开发服务器 worker 数量(多核本机可酌情打开) # PHP_CLI_SERVER_WORKERS=4 +# ============================================================================= +# CORS(跨域;config/cors.php) +# ============================================================================= + +# 浏览器跨域访问 API 的来源白名单,逗号分隔(协议+域名+可选端口) +# 示例: +# CORS_ALLOWED_ORIGINS=https://admin.example.com,https://partner-a.com +CORS_ALLOWED_ORIGINS= +# 可选:来源正则模式(需要受控通配时再用) +# CORS_ALLOWED_ORIGINS_PATTERNS=^https://([a-z0-9-]+)\.partner\.example\.com$ +CORS_ALLOWED_ORIGINS_PATTERNS= +# 预检缓存秒数;0 表示不缓存 +CORS_MAX_AGE=0 +# 是否允许跨站 Cookie(仅在确实需要浏览器跨站会话时设 true) +CORS_SUPPORTS_CREDENTIALS=false + # ============================================================================= # 密码哈希(config/hashing.php) # ============================================================================= diff --git a/config/cors.php b/config/cors.php new file mode 100644 index 0000000..db89b4c --- /dev/null +++ b/config/cors.php @@ -0,0 +1,87 @@ + trim($origin), + explode(',', (string) env('CORS_ALLOWED_ORIGINS', '')) +), static fn (string $origin): bool => $origin !== '')); + +$allowedOriginsPatterns = array_values(array_filter(array_map( + static fn (string $pattern): string => trim($pattern), + explode(',', (string) env('CORS_ALLOWED_ORIGINS_PATTERNS', '')) +), static fn (string $pattern): bool => $pattern !== '')); + +return [ + /* + |-------------------------------------------------------------------------- + | CORS Paths + |-------------------------------------------------------------------------- + | + | Only API and broadcasting/auth endpoints need CORS handling. + | + */ + 'paths' => ['api/*', 'broadcasting/auth'], + + /* + |-------------------------------------------------------------------------- + | Allowed Methods + |-------------------------------------------------------------------------- + */ + 'allowed_methods' => ['*'], + + /* + |-------------------------------------------------------------------------- + | Allowed Origins + |-------------------------------------------------------------------------- + | + | Use explicit domain whitelist in production. Do not use *. + | + */ + 'allowed_origins' => $allowedOrigins, + + /* + |-------------------------------------------------------------------------- + | Allowed Origin Patterns + |-------------------------------------------------------------------------- + | + | Optional regex-style patterns for controlled wildcard subdomains. + | + */ + 'allowed_origins_patterns' => $allowedOriginsPatterns, + + /* + |-------------------------------------------------------------------------- + | Allowed Headers + |-------------------------------------------------------------------------- + */ + 'allowed_headers' => ['*'], + + /* + |-------------------------------------------------------------------------- + | Exposed Headers + |-------------------------------------------------------------------------- + */ + 'exposed_headers' => [], + + /* + |-------------------------------------------------------------------------- + | Max Age + |-------------------------------------------------------------------------- + */ + 'max_age' => (int) env('CORS_MAX_AGE', 0), + + /* + |-------------------------------------------------------------------------- + | Supports Credentials + |-------------------------------------------------------------------------- + | + | Enable only if browser cross-site cookie auth is required. + | + */ + 'supports_credentials' => filter_var( + env('CORS_SUPPORTS_CREDENTIALS', false), + FILTER_VALIDATE_BOOL + ), +]; +