Laravel with Nginx parameters are empty
Asked Answered
S

6

7

I just set up Nginx, and I'm trying to use it to host a Laravel app, but I ran into 2 problems.

  1. For GET method, I always get an extra parameter in my inputs.
    • Using PostMan (Chrome) to do my testings, I set the destination URL and my desired parameters and send the request. The output that I get, it always includes the REQUEST_URI which it shouldn't. Example output:

.

Array (
  [/api/user] => // This shouldn't be here
  [test] => test
)
  1. My parameters (the above) will NOT show for DELETE or PUT, at all, and for POST I'll only get the REQUEST_URI

Nginx vhost (Followed Setting up Laravel w/ Nginx)

server {
    server_name local.test.com;
    root /var/www/test/public;

    location / {
        index index.php index.html index.htm;
    }

    # serve static files directly
    location ~* \.(jpg|jpeg|gif|css|png|js|ico|html)$ {
        access_log off;
        expires max;
    }

    # removes trailing slashes (prevents SEO duplicate content issues)
    if (!-d $request_filename) {
        rewrite ^/(.+)/$ /$1 permanent;
    }

    # unless the request is for a valid file (image, js, css, etc.), send to bootstrap
    if (!-e $request_filename) {
        rewrite ^/(.*)$ /index.php?/$1 last;
        break;
    }

    # catch all
    error_page 404 /index.php;

    # The PHP Inclusion Block
    # include /etc/nginx/includes/php;
    location ~ \..*/.*\.php$ {
        # I'm pretty sure this stops people trying to traverse your site to get to other PHP files
        return 403;
    }

    #location ~ \.php$ {
    location ~ \.php(.*)$ {
        try_files $uri =404;
        fastcgi_split_path_info ^(.+\.php)(/.+)$;
        fastcgi_pass 127.0.0.1:9000;
        fastcgi_index index.php;
        include /etc/nginx/fastcgi_params;
    }

# Deny Any Access to .htaccess Files That May Be Present (not usually in issue in Laravel)
# include /etc/nginx/includes/deny_htaccess;
location ~ /\.ht
{
    deny all;
}

    error_log  /var/www/logs/test-error.log;
}

fastcgi_params :

fastcgi_param   QUERY_STRING            $query_string;
fastcgi_param   REQUEST_METHOD          $request_method;
fastcgi_param   CONTENT_TYPE            $content_type;
fastcgi_param   CONTENT_LENGTH          $content_length;

fastcgi_param   SCRIPT_FILENAME         $request_filename;
fastcgi_param   SCRIPT_NAME             $fastcgi_script_name;
fastcgi_param   REQUEST_URI             $request_uri;
fastcgi_param   DOCUMENT_URI            $document_uri;
fastcgi_param   DOCUMENT_ROOT           $document_root;
fastcgi_param   SERVER_PROTOCOL         $server_protocol;

fastcgi_param   GATEWAY_INTERFACE       CGI/1.1;
fastcgi_param   SERVER_SOFTWARE         nginx/$nginx_version;

fastcgi_param   REMOTE_ADDR             $remote_addr;
fastcgi_param   REMOTE_PORT             $remote_port;
fastcgi_param   SERVER_ADDR             $server_addr;
fastcgi_param   SERVER_PORT             $server_port;
fastcgi_param   SERVER_NAME             $server_name;

#fastcgi_param  HTTPS                   $https;

# PHP only, required if PHP was built with --enable-force-cgi-redirect
fastcgi_param   REDIRECT_STATUS         200;

fastcgi_connect_timeout                 60;
fastcgi_send_timeout                    180;
fastcgi_read_timeout                    180;
fastcgi_buffer_size                     128k;
fastcgi_buffers 4                       256k;
fastcgi_busy_buffers_size               256k;
fastcgi_temp_file_write_size            256k;
fastcgi_intercept_errors                on;

nginx.conf Has only 1 thing changed, and that is keepalive_timeout from 65 to 15

So I absolutely have no clue, where all this thing goes wrong. But I do have to mention, that on another 2 environments that I have (One with Lighttpd and the other with Apache2) the app works perfectly.

From what I've noticed, its all reduced to the following code:

# unless the request is for a valid file (image, js, css, etc.), send to bootstrap
if (!-e $request_filename) {
    rewrite ^/(.*)$ /index.php?/$1 last;
    break;
}

Which will make the GET work... and add the additional parameter

Syconium answered 13/2, 2013 at 12:52 Comment(0)
C
6

It is best to avoid unneccessary rewrites in your nginx configuration (See Nginx Pitfalls), one in particular is the one responsible for passing the request to the Laravel front controller:

All you need for Laravel is:

location / {
    index index.php index.html index.htm;
    try_files $uri $uri/ index.php?$query_string;
}

First that tries to access a file directly, then a directory, and if neither exists it passes the request to index.php. $query_string is important to pass along as that will contain the $_GET data that otherwise gets lost.

And here is my own FastCGI configuration piece:

location ~ \.php$ {
    fastcgi_pass   127.0.0.1:9000;
    fastcgi_index  index.php;
    fastcgi_param  SCRIPT_FILENAME    $document_root/$fastcgi_script_name;
    include        fastcgi_params;
}

As for unexpected input, it could be the way your current rewrite works, but to say for sure, what are you outputting?

Cascara answered 13/2, 2013 at 13:15 Comment(6)
dd(Input::all()); it's what I'm outputting... and no, it's not Input::all() that set the undesired parameterSyconium
Alright. Try the suggested configuration and tell me if it does it.Cascara
Just tried it, by commenting the ifs containing a rewrite rule, and now I get no output of my parameters at allSyconium
Thanks for the help, but your conf is no of a help to me.Syconium
Have you replaced the part that you describe as "its all reduced to the following code" with my suggested code? I'm just not sure if that was clearCascara
Your suggested code regards anything ending in .php and accesing document root. even though, I do have tried your sugested code,and as mentioned, doesn't workSyconium
D
2

This works for me:

location / {
    index   index.php;
    try_files $uri $uri/ /index.php?q=$uri&$args;
}

location ~ \.php$ {

    include     fastcgi_params;
    fastcgi_pass   127.0.0.1:9000;
    fastcgi_index  index.php;

    fastcgi_split_path_info                 ^(.+\.php)(/.+)$;
    fastcgi_param PATH_INFO                 $fastcgi_path_info;
    fastcgi_param PATH_TRANSLATED           $document_root$fastcgi_path_info;
    fastcgi_param SCRIPT_FILENAME           $document_root$fastcgi_script_name;

}
Donnelly answered 24/2, 2013 at 9:39 Comment(2)
I don't think Laravel expects a q parameter, have not seen it before. But saw it in CISyconium
Yes, I've tested it without q and it works fine. So try_files $uri $uri/ /index.php?$args; works.Donnelly
C
1

From your config:

rewrite ^/(.*)$ /index.php?/$1 last;

here you have a redirect to /index.php?/$1 (e.g. /index.php?/some/path).

fastcgi_split_path_info ^(.+\.php)(/.+)$;

and here you spilt path by ^(.+\.php)(/.+)$ regex (e.g. /index.php/some/path).

Have you noticed the difference?

Chladek answered 18/2, 2013 at 17:13 Comment(6)
I actually removed the fastcgi_spli part and now I get the parameters, but I still have the [/api/user] => // This shouldn't be here problemSyconium
I followed https://mcmap.net/q/605497/-setting-up-laravel-with-nginx and just addapted a little bitSyconium
But you have configured nginx that way. Your rewrite ^/(.*)$ /index.php?/$1 last; is responsible for adding the path to the parameters.Chladek
please forgive my ignorance, but how else should I do it? That's what all the result I've seen on Google (searching laravel nginx) suggests.Syconium
You should do it the way that you want. Nginx has a very flexible configuration language, that allows to configure any desired behaviour. I suggest you to read the documentation and write your configuration from scratch. Useful links: nginx.org/en/docs and wiki.nginx.org/PitfallsChladek
Sorry, I cannot help because even don't know what laravel is, but it is clear to me that the example of configuration you have found is poorly written, probably by the person with a little knowledge of nginx.Chladek
P
1

I was facing similar issue and I fixed it with following configs:

server {
    listen 80;
    server_name subdomain.domain.com;
    root /var/www/dir/public;

    charset utf-8;

    location = /favicon.ico { access_log off; log_not_found off; }
    location = /robots.txt  { access_log off; log_not_found off; }

    access_log off;
    error_log  /var/log/nginx/registration.app-error.log error;
    error_page 404 /index.php;
    sendfile off;

    # Point index to the Laravel front controller.
    index index.php;

    location / {
       # try_files $uri $uri/ index.php?$query_string;
        try_files $uri $uri/ /index.php?&$args;
    }

    location ~ \.php$ {
                include snippets/fastcgi-php.conf;
        #
        #       # With php7.0-cgi alone:
        #       fastcgi_pass 127.0.0.1:9000;
        #       # With php7.0-fpm:
                fastcgi_pass unix:/run/php/php7.2-fpm.sock;
    }



    location ~ /\.ht {
        #deny all;
    }
}
Puff answered 21/6, 2018 at 1:15 Comment(1)
The only one that worked for me, critical bit was index.php?&$args;, running Laravel 4.2 and php7.0 on debian 9.6Aldridge
T
0

This is a configuration that works for me with NGINX and Laravel

server {

    listen  80;
    server_name sub.domain.com;
    set $root_path '/var/www/html/application_name/public';
    root $root_path;

    index index.php index.html index.htm;

    try_files $uri $uri/ @rewrite;

    location @rewrite {
        rewrite ^/(.*)$ /index.php?_url=/$1;
    }

    location ~ \.php {

        fastcgi_pass 127.0.0.1:9000;
        fastcgi_index /index.php;

        include /etc/nginx/fastcgi_params;

        fastcgi_split_path_info       ^(.+\.php)(/.+)$;
        fastcgi_param PATH_INFO       $fastcgi_path_info;
        fastcgi_param PATH_TRANSLATED $document_root$fastcgi_path_info;
        fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
    }

    location ~* ^/(css|img|js|flv|swf|download)/(.+)$ {
        root $root_path;
    }

    location ~ /\.ht {
        deny all;
    }

}
Transcurrent answered 13/1, 2014 at 15:18 Comment(0)
C
0

Same issue fixed as described in NGINX documentation: Embedded Variables: $is_args

Add this in NGINX location:

location / {
    try_files $uri $uri/ /index.php$is_args$args;
}
Congregate answered 7/1, 2023 at 18:24 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.