Nginx未转发Laravel Sanctum CSRF Cookie问题求助
问题排查与解决方案
一、Laravel Sanctum 核心配置检查
确认
.env关键参数:SESSION_DOMAIN:必须匹配前端和后端的共同域名(本地开发设为localhost,生产环境设为实际域名,如example.com)SANCTUM_STATEFUL_DOMAINS:列出所有允许携带Cookie的前端域名/端口,示例:localhost:3000,localhost:8000(逗号分隔,无空格)SESSION_SECURE_COOKIE:本地开发设为false(若用HTTP),生产环境HTTPS下设为trueSESSION_DRIVER:若用默认file,需确保PHP容器内storage/framework/sessions目录有写入权限
验证 Sanctum 安装与路由:
- 确认已执行
php artisan sanctum:install - 检查
config/sanctum.php中middleware配置是否包含web中间件(/sanctum/csrf-cookie依赖web中间件处理会话)
- 确认已执行
二、Nginx 反向代理配置修正
Nginx需正确传递请求头、处理CORS并转发到PHP-FPM,以下是适配的配置示例:
server { listen 80; server_name localhost; root /var/www/html/public; index index.php index.html; location / { try_files $uri $uri/ /index.php?$query_string; } # 处理CORS预请求(OPTIONS) if ($request_method = OPTIONS) { add_header Access-Control-Allow-Origin "http://localhost:3000"; # 替换为你的前端地址 add_header Access-Control-Allow-Methods "GET, POST, PUT, DELETE, OPTIONS"; add_header Access-Control-Allow-Headers "Content-Type, Authorization, X-XSRF-TOKEN"; add_header Access-Control-Allow-Credentials "true"; return 204; } # 常规请求的CORS头 add_header Access-Control-Allow-Origin "http://localhost:3000"; add_header Access-Control-Allow-Credentials "true"; location ~ \.php$ { fastcgi_pass php:9000; # 对应docker-compose中PHP服务名 fastcgi_index index.php; fastcgi_param SCRIPT_FILENAME $realpath_root$fastcgi_script_name; include fastcgi_params; # 传递真实客户端IP和协议,确保Laravel识别正确环境 fastcgi_param HTTP_X_FORWARDED_FOR $remote_addr; fastcgi_param HTTP_X_FORWARDED_PROTO $scheme; # 确保Cookie头正确传递 fastcgi_param HTTP_COOKIE $http_cookie; } }
注意:
Access-Control-Allow-Origin必须指定具体前端地址,不能用*(携带Cookie时浏览器不允许通配符)
三、Docker 环境配置调整
- docker-compose.yml:确保Nginx和PHP服务在同一网络,示例:
version: '3.8' services: nginx: image: nginx:1.25 ports: - "8000:80" volumes: - ./backend:/var/www/html - ./nginx/default.conf:/etc/nginx/conf.d/default.conf networks: - app-network depends_on: - php php: build: ./backend volumes: - ./backend:/var/www/html networks: - app-network environment: - APP_ENV=local - SESSION_DOMAIN=localhost - SANCTUM_STATEFUL_DOMAINS=localhost:3000,localhost:8000 networks: app-network: driver: bridge
- PHP Dockerfile:添加会话目录权限设置,避免无法写入会话文件:
FROM php:8.2-fpm # 安装依赖(省略部分,根据你的需求) RUN apt-get update && apt-get install -y \ git \ zip \ unzip # 安装Laravel所需扩展(如pdo_mysql等) RUN docker-php-ext-install pdo_mysql # 设置storage目录权限 RUN chown -R www-data:www-data /var/www/html/storage RUN chmod -R 755 /var/www/html/storage
四、Postman 测试注意事项
- 开启 Settings > Cookies > Send cookies
- 在请求头中添加
Origin: http://localhost:3000(模拟前端跨域请求) - 检查响应头是否包含
Set-Cookie,若存在则说明后端配置正常,前端需确保请求携带credentials: 'include'(React axios示例:axios.get('/sanctum/csrf-cookie', { withCredentials: true }))
五、最终验证步骤
- 重启所有Docker容器:
docker-compose down && docker-compose up -d - 清除Laravel缓存:
docker-compose exec php php artisan config:clear && php artisan cache:clear - 再次请求
/sanctum/csrf-cookie,查看响应状态码(应为204)及Set-Cookie头
内容的提问来源于stack exchange,提问作者Mohamed Hamidi
相关产品推荐
相关产品推荐

