我正在运行一个结合了nodejs和php的项目,nodejs的部分是一个SSR nuxt(类似于next(。
对/api/*
的请求将由laravel构建的php处理,对/*
的请求将被运行在3000
端口上的nodejs处理。
nginx配置的关键部分如下:
location /api/ {
try_files $uri $uri/ /index.php?$query_string;
}
location / {
proxy_pass http://127.0.0.1:3000;
}
它是如何工作的
- 当客户端通过在地址栏中键入来访问网站时,请求将首先由nodejs处理
- 然后,nodejs将向laravel发送一个数据请求
- 最后,nodejs将已经用laravel中的数据呈现的html发送到客户端
所以,问题是:
我在laravel中使用了Throttle,这意味着laravel需要真正的ip。
每次新用户通过在地址栏中输入来网站时,都会有一个来自nodejs的请求,并且laravel会认为它的ip是127.0.0.1
,即使真正的请求是从不同的ip发送的,nodejs也会得到429 Too Many Requests
响应。
如何解决:
我配置了configs/trustedproxy.php
:
<?php
return [
'proxies' => '127.0.0.1',
'headers' => IlluminateHttpRequest::HEADER_X_FORWARDED_ALL,
];
在nginx-config:中添加了proxy_set_header X-Forwarded-For $remote_addr;
proxy_set_header X-Forwarded-For $remote_addr;
location /api/ {
try_files $uri $uri/ /index.php?$query_string;
}
location / {
proxy_pass http://127.0.0.1:3000;
}
我确信我在appHttpKernel.php
中注册了TrustProxies::class
作为中间件,也重新启动了nginx,但它仍然不起作用。拉拉威尔仍然无法获得真正的ip。
我正在使用Laravel 8.12。
我该如何解决?我在谷歌上搜索了一下,但没有任何帮助。
非常感谢!我英语不好,很抱歉语法错误。
最后,我解决了这个bug。
严格来说,它不是一个代理,你不能完全像代理一样处理它。
nodejs将被Laravel视为客户端,因此必须修改一些javascript:
当客户端通过在地址栏中键入来访问网站时,nodejs应该在服务器端(而不是php或客户端的浏览器(获得真正的ip,然后用该ip向laravel发出请求,该ip将被添加为X-Forwarded-For
因此,在一个SSR Nuxt项目中:
plugins/axios.js
import axios from 'axios';
export default ({ req }) => {
axios.interceptors.request.use(request => {
...
if (process.server) {
request.headers.common['X-Forwarded-For'] = req.headers['x-forwarded-for'];
}
return request;
});
...
}