Laravel TrustProxies can not get real ip for Throttle - laravel

I am running a project which combines both nodejs and php, and the part of nodejs is a SSR nuxt (sth like next).
and requests for /api/* will be handled by php which constructed by laravel, requests for /* will be handled by nodejs which is running on 3000 port.
The key part of nginx configs is below:
location /api/ {
try_files $uri $uri/ /index.php?$query_string;
}
location / {
proxy_pass http://127.0.0.1:3000;
}
How it works?
When a client come to the website by typing in address bar, the request will be handled by nodejs first.
Then, nodejs will send a request to laravel for data.
Finally, the nodejs will send the html which had already been rendered with data from laravel to the client.
So, here is the problem:
I am using a Throttle in laravel, which means laravel needs the real ip.
Every time when a new user come to the website by typing in address bar, there is a request sent from nodejs, and the laravel will considered its ip is 127.0.0.1, a 429 Too Many Requests response will be got by nodejs even the real requests are sent from different ips.
How I try to solve:
I configed the configs/trustedproxy.php:
<?php
return [
'proxies' => '127.0.0.1',
'headers' => Illuminate\Http\Request::HEADER_X_FORWARDED_ALL,
];
added proxy_set_header X-Forwarded-For $remote_addr; in nginx config:
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;
}
I am sure I registered the TrustProxies::class as middleware in app\Http\Kernel.php, also restarted nginx, but it still not work. Laravel still can't get the real ip.
I am using Laravel 8.12.
How can I solve it?
I googled it but nothing helped.
Thanks a lot! I am not good at English, sorry for grammatical errors.

Finally, I work out this bug.
Strictly speaking, it's not a proxy which you can't handle it as same as proxy exactly.
The nodejs will be considered as a client by Laravel, so some javascript have to be modified:
When a client come to the website by typing in address bar, nodejs should get the real ip in server side(not the php nor client's browser), then make a request to laravel with that ip which will be added as X-Forwarded-For
so, in a SSR Nuxt project:
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;
});
...
}

Related

Redirect path based URL setup with Kubernetes ingress virtual service to a specific deployment having Laravel App

i have a setup which contain a domain, say:
https://my-apps-xyz.io => this is just a random/imaginary domain. An example.
I have setup in Kubernetes virtual service several apps to have the same domain but redirect in their respective deployment through the path.
So,
https://my-apps-xyz.io/app1 => app1 deployment/pod
https://my-apps-xyz.io/app2 => app2 deployment/pod
I have already successfully setup a redirection to 2 Nuxt.js apps. The third one, i want to temporarily configure for a Laravel App which is using Nginx as a reverse proxy.
How can i make/configure so the path based url successfully maps/routes in the Laravel app, is it more convenient to configure on Nginx level or Laravel app.
I tried already in Laravel
public function map()
{
Route::prefix('app3')->group(function () {
$this->mapApiRoutes();
});
//
}
But, the issue with this approach is that the bundled app.js and main.css are mapped into
https://my-apps-xyz.io/js/app.js
https://my-apps-xyz.io/css/main.css
instead of
https://my-apps-xyz.io/app3/js/app.js
https://my-apps-xyz.io/app3/css/main.css
Which ofcourse gives 404 error. How can i encompass both the web routes and api routes in Laravel to be prefixed with that path. Or better, if it's better to be done solely on nginx level, i welcome suggestions.
I already tried something like this in nginx default.conf file
location /app3/ {
root /var/www/html/app3/public;
try_files $uri $uri/ /index.php?$query_string;
}
Thanks in advance.

/api route not reachable after installing Laravel application to Amazon Elastic Beanstalk

I've just installed my Laravel application and it loads perfectly. I'm trying to make an api request from my machine to the application and from Vue.js application hosted on S3. Both attempts return 404, and in the browser console it says that I have a CORS problem. Ok, but I've installed fruitcake/cors, and this works locally. Also, I've seen that on AWS, when I try to reach /api/xxx/xxx, index.php is never reached. If I try without the /api prefix, it's reachable. Could that be a missconfiguration of nginx (I'm using the default configuration, and haven't changed anything)? Any help will be much appreaciated!
Like I was thinking, nginx is not configured properly by default. After I've added
location / {
try_files $uri $uri/ /index.php?$query_string;
}
everything worked.
I am leaving this topic if anyone else has the same problem.

Sinatra Session Not Persisting On Post

I am currently running a sinatra app using puma and an nginx reverse proxy. Sessions and cookies persist fine on any get requests as seen by logging:
{"user_id"=>1, "session_id"=>"89bb966142230a06fb5103db746c3011a741d88c7759dc2bff00c6bdd597c946"}
The user_id being the important part that signifies the session maintained its info. However as soon as I attempt to post through a form I instead lose this critical info:
"POST /price HTTP/1.0" 302 - 0.0045
{"session_id"=>"89bb966142230a06fb5103db746c3011a741d88c7759dc2bff00c6bdd597c946"}
My sinatra config for sessions is:
use Rack::Session::Cookie, :key => 'rack.session',
:path => '/',
:secret => ENV['secret']
Which seems to be working fine in all other scenarios of the app.
My Nginx reverse proxy settings for this app are:
server {
root /var/www/app/public;
access_log /var/www/app/var/log/nginx_access.log;
error_log /var/www/app/var/log/nginx_error.log;
location / {
try_files $uri #app;
}
location #app {
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header Host $http_host;
proxy_pass http://admin_server;
proxy_pass_request_headers on;
proxy_cookie_domain localhost $http_host;
}
#certbot ssl stuff
}
I'm at a relative loss now, as every other aspect of the authentication checks and session persistance seem to work fine, but the form post falls apart. Any guidance and help would be immensely helpful!

redirect in spring mvc under nginx work incorrect

Good day!
I have a little problem: My Spring MVC application is located by http://localhost:8080/webapp/ address. I've installed nginx for redirecting requests like somedomain.com to my app:
server{
server_name somedomain.com;
access_log /var/log/app.log;
location /{
proxy_pass http://localhost:8080/webapp/;
include /etc/nginx/proxy.conf;
}
proxy.conf:
proxy_redirect off;
proxy_set_header Host $host:$server_port;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
In one of controller method I use redirect, like that:
#RequestMapping(value = "/xxx", method = RequestMethod.POST)
public String xxx(ModelMap modelMap) {
return "redirect:/yyy";
}
After that, browser should open http://somedomain.com/yyy, but it looks for http://somedomain.com/webapp/yyy.
What I'm doing wrong?
Thanks for help.
I see that no one answered this but for future needs I will.
First you need to add virtual host in tomcat for your domain and map your app to it.
Next:
Change
http://localhost:8080/webapp/;
To
How it works :
When you add virtual host in tomcat in server.xml under engine tag
you say to tomcat that I want you to map this domain to my webapp. So any request comes to tomcat has the domain name in the header then tomcat will forward it to the webapp
Second
In nginx.conf
Under HTTP tag you will add server tag that listen to port 80 and a specific server name
Listen 80;
server_name somedomain.com;
So the request comes to the server tag then it will map it to the location tag
location /{
proxy_pass http://localhost:8080/webapp/; //this need to be change and remove the webapp context
include /etc/nginx/proxy.conf;
}
Last the request will be forwarded to tomcat and there the vHost will continue the job

Golang Goji: How to serve static content and api at the same time

I have been playing with Golang for the last two weeks and finally could make a real application work. It uses static HTML files served by NGINX and the API is using Goji Web Framework as backend. I don't use any Golang templating because everything is Angular.Js, so static is fine for my needs.
I would like to have the option to chose whether to use NGINX on production or let Go serve the static content at root using the same port the application uses (8000). This way development environments would not require NGINX to be installed.
So, tried adding a handle to the default mux like this
goji.DefaultMux.Handle("/*", serveStatic)
func serveStatic(w http.ResponseWriter, r *http.Request) {
//http.ServeFile(w, r, r.URL.Path[1:])
//http.FileServer(http.Dir("static"))
http.StripPrefix("/static/", http.FileServer(http.Dir("static")))
}
This handle is executed just after all the API paths have been registered (otherwise API would not work).
I already tried any sort of combination and either it redirects me to HTTP 404 or it displays the HTML content as text. Neither is good. I wonder if anyone has been here and could give me a heads up on what am I doing wrong.
Thanks.
Although this has nothing to do with my issue, here is the NGINX configuration I am using:
server {
listen 80;
# enable gzip compression
gzip on;
gzip_min_length 1100;
gzip_buffers 4 32k;
gzip_types text/plain application/x-javascript text/xml text/css;
gzip_vary on;
# end gzip configuration
location / {
root /home/mleyzaola/go/src/bitbucket.org/mauleyzaola/goerp/static;
try_files $uri $uri/ /index.html = 404;
}
location /api {
proxy_pass http://localhost:8000;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection 'upgrade';
proxy_set_header Host $host;
proxy_cache_bypass $http_upgrade;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
}
}
I had run into similar issues so perhaps the following points would be helpful.
Remember to register the handler for serving static content as the final route. Otherwise, it might match everything.
Perhaps try using absolute paths instead of relative ones.
Here's a simplified version of how my routes are set up with Goji.
func apiExampleHandler(context web.C, resp http.ResponseWriter, req *http.Request) {
fmt.Fprint(resp, "You've hit the API!")
}
func main() {
goji.Handle("/api", apiExampleHandler)
// Static file handler should generally be the last handler registered. Otherwise, it'll match every path.
// Be sure to use an absolute path.
staticFilesLocation := "Some absolute to the directory with your static content."
goji.Handle("/*", http.FileServer(http.Dir(staticFilesLocation)))
goji.Serve()
}
If you have full control over your URLs, a simple strategy is to divide them at the top level. I use /a at the start of all application URLs and /s at the start of all static URLs. This makes the routing very simple.
I was using Goji for a while, then switched to Gocraft-web. But the principles are the same in that the URLs will be unambiguous with either framework. Gocraft-web can obviously do subrouting; I think Goji can also do this but it's less obvious. Subrouting is helpful for several reasons:
its an easy way to remove ambiguity
the router might well be faster if its search patterns are simpler
you can divide your code so it might be easier to understand
If you are serving static assets in production, you may like to measure it and improve its performance. I find that pre-compressing (gzip) my JS and CSS files can help. I have both uncompressed and compressed versions in the same file system and I have a bespoke static asset package that spots the pre-compressed files and serves them to all clients that understand (which is almost all browsers). Also, setting a future expiry date is worth exploring. Both of these ideas are built-into Nginx, and quite easy to code up with a bit of effort.

Resources