
Recentemente, mudamos do Apache para o Nginx. No Apache costumava ser muito fácil, basta colocar algumas coisas no .htaccess e pronto.
RewriteEngine on
RewriteBase /
# only rewrite if the requested file doesn't exist
RewriteCond %{REQUEST_FILENAME} !-s
# pass the rest of the request into index.php to handle
RewriteRule ^(.*)$ /index.php/$1 [L]
O texto acima foi ótimo para limpar URL e deixar index.php lidar com todas as solicitações. mas no Nginx precisávamos reescrever cada URL exclusivo no bloco de localização. No entanto, isso não é 'automático' como o Apache.
Alguns exemplos do nosso bloco de localização de reescrita
location / {
try_files $uri $uri/ /index.php;
}
location /p {
rewrite ^/p(?:/([a-z_]+))?$ /index.php?p=$1 last;
rewrite ^/p/all_articles/user/(.*)?$ /index.php?p=all_articles&user=$1 last;
try_files $uri $uri/ /index.php;
}
location /about_us {
rewrite ^/about_us /index.php?about_us last;
try_files $uri $uri/ /index.php;
}
location /search {
rewrite ^/search/(.*) /index.php?search=$1;
rewrite ^/search/(.*)/page/(.*)?$ /index.php?search=$1&page=$2 last;
try_files $uri $uri/ /index.php;
}
location ~ \.php$ {
include snippets/fastcgi-php.conf;
fastcgi_pass unix:/var/run/php/php7.0-fpm.sock;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
include fastcgi_params;
}
o acima faz um bom trabalho em URL limpo, mas quando precisamos obter páginas, por exemplo
/p/all_articles/user/ABC/page/2
/index.php?p=all_articles&user=ABC&page=2
nós tentamos
rewrite ^/p/all_articles/user/(.*)/pg(?:/([0-9]+))?$ /index.php?p=all_articles&user=$1&pg=$2 last;
isso só funciona quando colocamos em um bloco de localização separado
location /page/all_articles {
rewrite ^/p/all_articles/user/(.*)/pg(?:/([0-9]+))?$ /index.php?p=all_articles&user=$1&pg=$2 last;
try_files $uri $uri/ /index.php;
}
e quando feito isso, não deixaria
/p/todos_artigos/usuário/ABC
para carregar.
além disso, as páginas de resultados de pesquisa não funcionariam de todo.
outro problema que encontramos está na pasta .htaccess
Order deny,allow
Deny from all
Options -Indexes
No Apache, isso impediria qualquer acesso a essa pasta e arquivos, exceto o script php. Nós tentamos,
location /(data|img)/ {
deny all;
return 404;
}
Ele bloqueia o acesso à pasta, mas, se você especificar o nome do arquivo, ele ainda servirá, sem negar o acesso, por exemplo;
/data/backup_01012020.zip no apache .htaccess, apenas alguns usuários tiveram permissão para acessá-lo, enquanto estavam logados. e fora dele, o apache negará qualquer acesso. Mas no nginx, embora dê 404 ao tentar acessar/data/. Mesmo quando você não estiver logado, ele servirá o arquivo backup_01012020.zip imediatamente.
Agora não conseguimos descobrir o que podemos fazer, o que costumava ser moleza com o Apache. Nosso aplicativo é baseado em PHP e index.php é capaz de lidar com todas as solicitações de URL limpas. Poderia ter sido ótimo se o Nginx simplesmente passasse todas as solicitações para indexar e permitisse que ele fosse processado, em vez de muitas reescritas e blocos de localização. Qualquer ajuda seria ótimo.
Responder1
Você pode estar interessado nas perguntas com oreescrever etiqueta, pois contém muitas variações do seu problema.
Sua regra de reescrita do Apache:
RewriteRule ^(.*)$ /index.php/$1 [L]
anexa todo o URI da solicitação a /index.php
. Emnginxocaminhodo URI (normalizado) está disponível no$urivariável. Se você também precisar dos argumentos de consulta, poderá usar o$request_uriem vez de.
Uma tradução estrita de suas regras de reescrita seria, portanto:
location / {
# Size zero static files are served.
# I don't believe that is an issue.
try_files $uri /index.php$request_uri;
}
# If no other .php files are accessible a prefix location of '/index.php/'
# is safer.
location /index.php/ {
include snippets/fastcgi-php.conf;
fastcgi_pass unix:/var/run/php/php7.0-fpm.sock;
# Probably duplicates the contents of fastcgi-php.conf
# fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
# include fastcgi_params;
}
Sua deny
diretiva sobre o /(data|img)/
local não funciona, pois você está usando uma correspondência de prefixo, em vez de uma correspondência de regex:
location ~ ^/(data|img)/ {
# Only one is required
deny all;
# return 404;
}
Responder2
Solução para reescrever
location /search {
rewrite ^/search/(.*)/page/(.*)?$ /index.php?search=$1&page=$2 last;
rewrite ^/search/(.*) /index.php?search=$1 last;
try_files $uri $uri/ /index.php;
}
location /p/all_articles {
rewrite ^/p/all_articles/user/(.*)/page(?:/([0-9]+))?$ /index.php?p=all_articles&user=$1&page=$2 last;
rewrite ^/p/all_articles/user/(.*)?$ /index.php?p=all_articles&user=$1 last;
try_files $uri $uri/ /index.php;
}
Observe, tudo que fiz foi trocar linhas. Créditos paraRicardo Smith
Graças aPiotr P. Karwasz, para a outra solução, pode ajudar alguém cujo script é 100% compatível a lidar com URL limpo por conta própria.
location / {
# Size zero static files are served.
# I don't believe that is an issue.
try_files $uri /index.php$request_uri;
}
# If no other .php files are accessible a prefix location of '/index.php/'
# is safer.
location /index.php/ {
include snippets/fastcgi-php.conf;
fastcgi_pass unix:/var/run/php/php7.0-fpm.sock;
# Probably duplicates the contents of fastcgi-php.conf
# fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
# include fastcgi_params;
}
a solução acima é uma boa opção, desde que seu script funcione 100% com URL limpo. Aqui, você não precisa colocar centenas de blocos de localização reescritos, e o nginx anexará todo o URI da solicitação a /index.php, o que é muito interessante e útil, provavelmente esta é a solução real, mas no meu caso meu script não era 100 % compatível com isso. Ainda assim, esta é uma solução boa e inteligente.
Solução para impedir acesso a pastas e arquivos
location ~ ^/(data|img)/ {
# Only one is required
deny all;
# return 404;
}
Créditos paraPiotr P. Karwaszapontou que deny all
estava sendo substituído por algo; após limpar o bloqueio do servidor, o problema foi resolvido. Certifique-se também de usar deny all;
ou return 404;
mas não juntos.