Nginx FPM PHP Ubuntu $_POST not being populated - fastcgi

I have a server with NGNIX and PHP setup. The php script doesn't seem to have $_POST variable populated. I have checked the usual suspects, NGINX configuration, PHP.ini, etc. Not sure what I am doing wrong
location /ffc {
include /etc/nginx/mime.types;
index index.html index.php;
root /var/www/;
# pass the PHP scripts to FastCGI server listening on 127.0.0.1:9000
location ~ \.php$ {
try_files $uri =404;
include fastcgi_params;
fastcgi_pass unix:/var/run/php5-fpm.sock;
fastcgi_index index.php;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
fastcgi_param PATH_INFO $fastcgi_script_name;
fastcgi_pass_request_body on;
fastcgi_pass_request_headers on;
fastcgi_param REQUEST_BODY $request_body;
}
}
<?php
var_dump($HTTP_RAW_POST_DATA);
var_dump($file= file_get_contents('php://input'));
var_dump($_REQUEST);
var_dump($GLOBALS);
echo 'HEADERS <br/>';
var_dump(get_headers());
?>
string(64) "fullname=test email=john#gmail.com message=dfadfsasdfas" array(0) { } array(8) { ["HTTP_RAW_POST_DATA"]=> string(64) "fullname=test email=john#gmail.com message=dfadfsasdfas" ["_GET"]=> array(0) { } ["_POST"]=> array(0) { } ["_COOKIE"]=> array(7) { ["uid"]=> string(24) "CqQw7lMQ9JNQwkpwAwMpAg==" ["_vis_opt_s"]=> string(2) "1|" ["_vis_opt_test_cookie"]=> string(1) "1" ["mp_f6e7292aa77905eaaf9137d271097d72_mixpanel"]=> string(144) "{"distinct_id": "1447a3b515f188-069aadc7a-1b10435d-1fa400-1447a3b51603ef","$initial_referrer": "$direct","$initial_referring_domain": "$direct"}" ["ip"]=> string(13) "" ["iso2"]=> string(0) "" ["iso3"]=> string(0) "" } ["_FILES"]=> array(0) { } ["GLOBALS"]=> RECURSION ["_SERVER"]=> array(41) { ["USER"]=> string(8) "www-data" ["HOME"]=> string(8) "/var/www" ["FCGI_ROLE"]=> string(9) "RESPONDER" ["QUERY_STRING"]=> string(0) "" ["REQUEST_METHOD"]=> string(4) "POST" ["CONTENT_TYPE"]=> string(10) "text/plain" ["CONTENT_LENGTH"]=> string(2) "64" ["SCRIPT_FILENAME"]=> string(34) "/var/www/test/ffc/sendmail.php" ["SCRIPT_NAME"]=> string(17) "/ffc/sendmail.php" ["REQUEST_URI"]=> string(17) "/ffc/sendmail.php" ["DOCUMENT_URI"]=> string(17) "/ffc/sendmail.php" ["DOCUMENT_ROOT"]=> string(17) "/var/www/test" ["SERVER_PROTOCOL"]=> string(8) "HTTP/1.1" ["GATEWAY_INTERFACE"]=> string(7) "CGI/1.1" ["SERVER_SOFTWARE"]=> string(12) "nginx/1.5.10" ["REMOTE_ADDR"]=> string(13) "" ["REMOTE_PORT"]=> string(4) "1572" ["SERVER_ADDR"]=> string(13) "" ["SERVER_PORT"]=> string(2) "80" ["SERVER_NAME"]=> string(12) "test.com" ["REDIRECT_STATUS"]=> string(3) "200" ["PATH_INFO"]=> string(17) "/ffc/sendmail.php" ["REQUEST_BODY"]=> string(64) "fullname=test email=john#gmail.com message=dfadfsasdfas" ["HTTP_HOST"]=> string(12) "test.com" ["HTTP_ACCEPT"]=> string(74) "text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,/;q=0.8" ["HTTP_ACCEPT_ENCODING"]=> string(17) "gzip,deflate,sdch" ["HTTP_ACCEPT_LANGUAGE"]=> string(14) "en-US,en;q=0.8" ["HTTP_CACHE_CONTROL"]=> string(9) "max-age=0" ["HTTP_CONTENT_TYPE"]=> string(10) "text/plain" ["HTTP_COOKIE"]=> string(344) "uid=CqQw7lMQ9JNQwkpwAwMpAg==; _vis_opt_s=1%7C; _vis_opt_test_cookie=1; mp_f6e7292aa77905eaaf9137d271097d72_mixpanel=%7B%22distinct_id%22%3A%20%221447a3b515f188-069aadc7a-1b10435d-1fa400-1447a3b51603ef%22%2C%22%24initial_referrer%22%3A%20%22%24direct%22%2C%22%24initial_referring_domain%22%3A%20%22%24direct%22%7D; ip=; iso2=; iso3=" ["HTTP_ORIGIN"]=> string(19) "http://test.com" ["HTTP_REFERER"]=> string(36) "http://test.com/ffc/contact.html" ["HTTP_USER_AGENT"]=> string(120) "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_8_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/33.0.1750.117 Safari/537.36" ["HTTP_X_FORWARDED_FOR"]=> string(14) "192.195.83.183" ["HTTP_X_FORWARDED_PORT"]=> string(2) "80" ["HTTP_X_FORWARDED_PROTO"]=> string(4) "http" ["HTTP_CONTENT_LENGTH"]=> string(2) "64" ["HTTP_CONNECTION"]=> string(10) "keep-alive" ["PHP_SELF"]=> string(17) "/ffc/sendmail.php" ["REQUEST_TIME_FLOAT"]=> float(1394500698.6063) ["REQUEST_TIME"]=> int(1394500698) } ["_REQUEST"]=> array(0) { } } HEADERS
NULL POST
array(0) { }

Related

why i get 'Access-Control-Allow-Origin' header contains multiple values from nginx

i get the following message in my browser:
Access to XMLHttpRequest at 'myApidomain.de' from origin 'myorigindomain.de' has been blocked by CORS policy: The 'Access-Control-Allow-Origin' header contains multiple values 'myorigindomain.de, myorigindomain.de', but only one is allowed.
The message is clear. But it wasnt clear if you take a look at my nginx default.conf:
server {
listen 8000 default_server;
listen [::]:8000 default_server ipv6only=on;
server_name localhost;
root /var/www/html/public;
index index.php index.html index.htm;
real_ip_header X-Forwarded-For;
add_header 'Access-Control-Allow-Methods' 'GET, POST, DELETE, OPTIONS, PATCH, PUT' always;
add_header "Access-Control-Allow-Headers" "Authorization, v-access-header, Origin, X-Requested-With, Content-Type, Accept";
add_header 'Access-Control-Allow-Credentials' 'true';
location / {
try_files $uri /index.php$is_args$args;
}
location ~ ^/(index)\.php(/|$) {
#fastcgi_pass php-upstream;
fastcgi_pass 127.0.0.1:9000;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
fastcgi_param REMOTE_ADDR $http_x_forwarded_for;
fastcgi_param DOCUMENT_ROOT $realpath_root;
#fixes timeouts
fastcgi_send_timeout 6000;
fastcgi_read_timeout 6000;
include fastcgi_params;
internal;
if ($request_method = 'OPTIONS') {
add_header 'Access-Control-Allow-Methods' 'GET, POST, OPTIONS, DELETE, PATCH, PUT' always;
add_header 'Access-Control-Allow-Headers' 'DNT,v-access-header,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type,Range,Authorization' always;
add_header 'Access-Control-Max-Age' 1728000;
add_header 'Access-Control-Allow-Credentials' 'true';
#add_header 'Content-Type' 'text/plain; charset=utf-8';
#add_header 'Content-Length' 0;
#return 204;
}
if ($request_method ~* "(GET|POST|PUT|PATCH|DELETE)") {
add_header 'Access-Control-Allow-Origin' "$http_origin" always;
add_header 'Access-Control-Allow-Methods' 'GET, POST, DELETE, OPTIONS, PATCH, PUT' always;
add_header "Access-Control-Allow-Headers" "Authorization, v-access-header, Origin, X-Requested-With, Content-Type, Accept" always;
add_header 'Access-Control-Allow-Credentials' 'true';
}
}
location ~ /\.ht {
deny all;
}
location /.well-known/acme-challenge/ {
root /var/www/letsencrypt/;
log_not_found off;
}
}
there is only 1 Header allow origin... why i get multiple? is there a way to find out where the second entry is coming from?
When i delete this entry my GET request dont work because "NO ALLOW-ORIGIN Header is present."
Now the GET is working and the POST make this error.

Multiple reactapp using docker

When i try to run mutiple reactapps using docker and nginx reverse proxy, iam getting an error : Upstream timed out while connecting to the upstream.
The error you can see in the below screenshot when i check the nginx logs
server {
listen 80;
return 301 https://$host$request_uri;
}
server {
listen 443 ssl default_server;
listen [::]:443 ssl default_server;
add_header 'Cache-Control' "public, max-age=31536000";
add_header Strict-Transport-Security "max-age=31536000; includeSubDomains" always;
add_header X-Frame-Options "SAMEORIGIN";
add_header X-XSS-Protection "1; mode=block";
add_header X-Content-Type-Options: "nosniff";
ssl_certificate /etc/nginx/conf.d/cert.crt;
ssl_certificate_key /etc/nginx/conf.d/ssl.key;
server_name <Domain-ip>;
location / {
proxy_pass http://domainname:3000;
#try_files $uri /index.html;
}
location /elderly {
proxy_pass http://domainname:3001;
#try_files $uri /index.html;
}
location /carer {
proxy_pass http://domainname:3002;
#try_files $uri /index.html;
}
#For gzip text compression
gzip on;
gzip_comp_level 2;
gzip_min_length 1000;
gzip_proxied expired no-cache no-store private auth;
gzip_types text/plain application/x-javascript text/xml text/css application/xml application/javascript
error_page 500 502 503 504 /50x.html;
location = /50x.html {
root /usr/share/nginx/html;
}
#For optimization
location ~* \.(ico|css|js|webp|gif|jpeg|jpg|png|woff|ttf|otf|svg|woff2|eot)$ {
expires 365d;
add_header Cache-Control "public, max-age=31536000";
}
}

Authenticator does not support the request

I have a Symfony 5.1 project that has login functionality.
When I use the Symfony CLI command symfony serve, the login on localhost just works.
But when I try the same login via Docker, nothing happens.
In the logs of my nginx container, I can see this message:
172.19.0.1 - - [24/Nov/2020:13:31:40 +0000] "POST /login HTTP/1.1" 302 282 "http://localhost:8088/login" "Mozilla/5.0 (Macintosh; Intel Mac OS X 11_0_1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/87.0.4280.67 Safari/537.36"
2020/11/24 13:31:41 [error] 27#27: *122 FastCGI sent in stderr: "PHP message: [info] Matched route "app_login".
PHP message: [debug] Checking for authenticator support.
PHP message: [debug] Checking support on authenticator.
PHP message: [debug] Authenticator does not support the request. ['firewall_name' => 'main', 'authenticator' => 'Symfony\Component\Security\Guard\Authenticator\GuardBridgeAuthenticator']
This is my config/packages/security.yaml:
security:
enable_authenticator_manager: true
providers:
users:
entity:
class: 'App\Entity\User'
encoders:
App\Entity\User:
algorithm: auto
firewalls:
dev:
pattern: ^/(_(profiler|wdt)|css|images|js)/
security: false
main:
anonymous: false
lazy: true
provider: users
guard:
authenticators:
- App\Security\LoginFormAuthenticator
logout:
path: app_logout
# where to redirect after logout
target: home
role_hierarchy:
ROLE_ADMIN: ROLE_USER
access_control:
- { path: ^/admin, roles: ROLE_ADMIN }
This is my docker/nginx/default.conf:
server {
listen 80;
index index.php index.html;
server_name localhost;
error_log /var/log/nginx/error.log;
access_log /var/log/nginx/access.log;
root /var/www/app/public;
proxy_buffer_size 128k;
proxy_buffers 4 256k;
proxy_busy_buffers_size 256k;
location / {
try_files $uri $uri/ /index.php?$query_string;
}
location ~ \.php$ {
try_files $uri =404;
fastcgi_split_path_info ^(.+\.php)(/.+)$;
fastcgi_pass php:9000;
fastcgi_index index.php;
include fastcgi_params;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
fastcgi_param PATH_INFO $fastcgi_path_info;
fastcgi_buffer_size 128k;
fastcgi_buffers 4 256k;
fastcgi_busy_buffers_size 256k;
}
}
This is my docker/php/Dockerfile:
FROM php:7.4-fpm
# Install Composer
RUN curl -sS https://getcomposer.org/installer | php -- \
--install-dir=/usr/local/bin \
--filename=composer
# Install MySQL
RUN docker-php-ext-install mysqli pdo pdo_mysql
WORKDIR /var/www/app
And my src/Security/LoginFormAuthenticator.php:
<?php
namespace App\Security;
...
use App\Entity\User;
...
class LoginFormAuthenticator extends AbstractFormLoginAuthenticator implements PasswordAuthenticatedInterface
{
use TargetPathTrait;
public const LOGIN_ROUTE = 'app_login';
private $entityManager;
private $urlGenerator;
private $csrfTokenManager;
private $passwordEncoder;
public function __construct(EntityManagerInterface $entityManager, UrlGeneratorInterface $urlGenerator, CsrfTokenManagerInterface $csrfTokenManager, UserPasswordEncoderInterface $passwordEncoder)
{
$this->entityManager = $entityManager;
$this->urlGenerator = $urlGenerator;
$this->csrfTokenManager = $csrfTokenManager;
$this->passwordEncoder = $passwordEncoder;
}
public function supports(Request $request)
{
return self::LOGIN_ROUTE === $request->attributes->get('_route')
&& $request->isMethod('POST');
}
public function getCredentials(Request $request)
{
$credentials = [
'email' => $request->request->get('email'),
'password' => $request->request->get('password'),
'csrf_token' => $request->request->get('_csrf_token'),
];
$request->getSession()->set(
Security::LAST_USERNAME,
$credentials['email']
);
return $credentials;
}
public function getUser($credentials, UserProviderInterface $userProvider)
{
$token = new CsrfToken('authenticate', $credentials['csrf_token']);
if (!$this->csrfTokenManager->isTokenValid($token)) {
throw new InvalidCsrfTokenException();
}
$user = $this->entityManager->getRepository(User::class)->findOneBy(['email' => $credentials['email']]);
if (!$user) {
// fail authentication with a custom error
throw new CustomUserMessageAuthenticationException('Email could not be found.');
}
return $user;
}
public function checkCredentials($credentials, UserInterface $user)
{
return $this->passwordEncoder->isPasswordValid($user, $credentials['password']);
}
public function getPassword($credentials): ?string
{
return $credentials['password'];
}
public function onAuthenticationSuccess(Request $request, TokenInterface $token, string $providerKey)
{
if ($targetPath = $this->getTargetPath($request->getSession(), $providerKey)) {
return new RedirectResponse($targetPath);
}
return new RedirectResponse($this->urlGenerator->generate('home'));
}
protected function getLoginUrl()
{
return $this->urlGenerator->generate(self::LOGIN_ROUTE);
}
}
What am I doing wrong that my Docker isn't recognizing my App\Security\LoginFormAuthenticator as Authenticator?
Thanks in advance!
EDIT: 22 February 2021
It looks like the form is redirecting itself without errors. I guess the the wrong Authenticator was used, but in my security.yaml file you see the correct guard.
Removing the anonymous: false setting did the trick.
Thanks #Cerad for your help!

Nginx server config for codeigniter in docker, multiple applications

I have index.php and manager.php for those 2 applications in root, setup though docker with nginx, phpfpm and some other dependencies.
This is my docker-compose file, I put only the important parts.
services:
web:
container_name: web
build:
context: ./
dockerfile: docker/nginx/Dockerfile
volumes:
- ./:/var/www
ports:
- 80
depends_on:
- app
environment:
VIRTUAL_HOST: ${VIRTUAL_HOSTS}
VIRTUAL_PORT: 80
networks:
- nginx-proxy
- my-app
app:
container_name: app
build:
context: ./
dockerfile: docker/php/Dockerfile
volumes:
- ./:/var/www
depends_on:
- mysql
ports:
- 9000
networks:
- my-app
...
And this is my vhost file, i tried everything i knew or found on the internet to make it work without success, this is final form, of course still not working.
server {
listen 80;
server_name myapplication.local;
index index.php index.html;
root /var/www;
location / {
try_files $uri $uri/ =404;
}
location /manager.php {
fastcgi_split_path_info ^(.+\.php)(/.+)$;
fastcgi_pass app:9000;
fastcgi_index manager.php;
include fastcgi_params;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
fastcgi_param PATH_INFO $fastcgi_path_info;
}
location ~ \.php$ {
fastcgi_split_path_info ^(.+\.php)(/.+)$;
fastcgi_pass app:9000;
fastcgi_index index.php;
include fastcgi_params;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
fastcgi_param PATH_INFO $fastcgi_path_info;
}
try_files $uri $uri/ /index.php;
if (!-e $request_filename){
rewrite ^/(.*)$ /index.php?/$1? last;
}
location ~ /\.ht {
deny all;
}
location = /favicon.ico {
log_not_found off; access_log off;
}
location = /robots.txt {
log_not_found off; access_log off; allow all;
}
location ~* \.(css|gif|ico|jpeg|jpg|js|png)$ {
expires max;
log_not_found off;
}
sendfile off;
}
If I access application normal works just fine, if I go to
/manager.php or /manager.php/* I get 404, does any knows how I can configure nginx to work with this situation, thanks!
I found the solution:
server {
listen 80;
server_name myapplication.local;
index index.php index.html manager.php;
root /var/www;
location / {
try_files $uri $uri/ =404;
}
location ~ \.php$ {
fastcgi_split_path_info ^(.+\.php)(/.+)$;
fastcgi_pass app:9000;
fastcgi_index index.php;
include fastcgi_params;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
fastcgi_param PATH_INFO $fastcgi_path_info;
}
try_files $uri $uri/ /index.php /manager.php;
if (!-e $request_filename){
rewrite ^/manager.php/(.*)$ /manager.php?/$1? last;
rewrite ^/(.*)$ /index.php?/$1? last;
}
location ~ /\.ht {
deny all;
}
location = /favicon.ico {
log_not_found off; access_log off;
}
location = /robots.txt {
log_not_found off; access_log off; allow all;
}
location ~* \.(css|gif|ico|jpeg|jpg|js|png)$ {
expires max;
log_not_found off;
}
sendfile off;
}

Varnish with Nginx for a Rails application (issue with Devise authentication)

I have the following configuration for Varnish. But when I access the application, it doesn't ask for login, it just login.
What I'm doing wrong?
default.vcl
backend default {
.host = "127.0.0.1";
.port = "80";
}
sub vcl_recv {
if(req.url ~ "sign_in" || req.url ~ "sign_out" || req.request == "POST" || req.request == "PUT" || req.request == "DELETE") {
return (pass);
}
return (lookup);
}
sub vcl_fetch {
if(req.url ~ "logout" || req.url ~ "sign_out"){
unset beresp.http.Set-Cookie;
}
if (req.request == "GET") {
unset beresp.http.Set-Cookie;
set beresp.ttl = 360m;
}
if (req.url ~ "images/" || req.url ~ "javascripts" || req.url ~ "stylesheets" || req.url ~ "assets"){
set beresp.ttl = 360m;
}
}
/etc/default/varnish
DAEMON_OPTS="-a 192.241.136.37:80 \
-T localhost:6082 \
-f /etc/varnish/default.vcl \
-S /etc/varnish/secret \
-s malloc,256m"
/etc/nginx/sites-enabled/default
upstream app {
server unix:/tmp/unicorn.socket fail_timeout=0;
}
server {
listen 80;
client_max_body_size 2G;
server_name localhost;
keepalive_timeout 5;
root /home/deploy/apps/wms/current/public;
access_log off;
error_log off;
if ($request_method !~ ^(GET|HEAD|PUT|POST|DELETE|OPTIONS)$ ){
return 405;
}
location ~ ^/(assets)/ {
gzip_static on;
expires max;
add_header Cache-Control public;
}
location / {
try_files $uri/index.html $uri.html $uri #app;
error_page 404 /404.html;
error_page 422 /422.html;
error_page 500 502 503 504 /500.html;
error_page 403 /403.html;
}
location #app {
proxy_pass http://app;
}
location = /favicon.ico {
expires max;
add_header Cache-Control public;
}
location ~ \.php$ {
deny all;
}
}
You are preventing your backend to delete your session cookie, so you can't log out unless you explicitly delete your browsers' cookies.
Looking at your fetch VCL (Comment inline):
sub vcl_fetch {
# This prevents server from deleting the cookie in the browser when loging out
if(req.url ~ "logout" || req.url ~ "sign_out"){
unset beresp.http.Set-Cookie;
}
if (req.request == "GET") {
unset beresp.http.Set-Cookie;
set beresp.ttl = 360m;
}
if (req.url ~ "images/" || req.url ~ "javascripts" || req.url ~ "stylesheets" || req.url ~ "assets"){
set beresp.ttl = 360m;
}
}
So your backend can't delete client's cookie unless as result of a POST request.
IMHO you shouldn't mess with backend's Set-Cookie headers unless you know (and test well) posible side effects

Resources