
최근에 우리는 Apache에서 Nginx로 옮겼습니다. Apache에서는 .htaccess에 몇 가지 항목을 추가하고 완료하는 것이 매우 쉬웠습니다.
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]
위의 내용은 URL을 정리하고 index.php가 모든 요청을 처리하도록 하는 데 유용했습니다. 하지만 Nginx에서는 위치 블록의 모든 고유 URL을 다시 작성해야 했습니다. 그러나 이것은 아파치처럼 '자동'이 아닙니다.
재작성 위치 블록의 몇 가지 예
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;
}
위의 내용은 깨끗한 URL에서는 잘 작동하지만 예를 들어 페이지를 가져와야 하는 경우에는
/p/all_articles/user/ABC/페이지/2
/index.php?p=all_articles&user=ABC&page=2
우리는 시도했다
rewrite ^/p/all_articles/user/(.*)/pg(?:/([0-9]+))?$ /index.php?p=all_articles&user=$1&pg=$2 last;
이는 별도의 위치 블록에 배치할 때만 작동합니다.
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;
}
그리고 그렇게 했을 때, 그것은 허락하지 않을 것입니다
/p/all_articles/user/ABC
로드합니다.
또한 검색 결과 페이지가 전혀 작동하지 않습니다.
우리가 발견한 또 다른 문제는 .htaccess 폴더에 있습니다.
Order deny,allow
Deny from all
Options -Indexes
아파치에서는 PHP 스크립트를 제외한 해당 폴더와 파일에 대한 액세스가 차단됩니다. 우리는 노력했다,
location /(data|img)/ {
deny all;
return 404;
}
폴더에 대한 액세스를 차단하지만, 파일 이름을 지정하면 액세스를 거부하지 않고 계속해서 서비스를 제공합니다.
apache .htaccess 아래의 /data/backup_01012020.zip, 로그인된 동안 특정 사용자만 이에 대한 액세스가 허용되었습니다. 그 외부에서는 Apache가 모든 액세스를 거부합니다. 그러나 nginx에서는 /data/에 액세스하려고 할 때 404가 표시되지만. 로그인하지 않아도 바로 backup_01012020.zip 파일을 서비스하게 됩니다.
이제 우리는 아파치를 사용하면 아주 간단했던 우리가 무엇을 할 수 있는지 알 수 없습니다. 우리 애플리케이션은 PHP를 기반으로 하며 index.php는 모든 깨끗한 URL 요청을 처리할 수 있습니다. Nginx가 단순히 모든 요청을 인덱스에 전달하고 많은 재작성 및 위치 블록 대신 처리하도록 했다면 좋았을 것입니다. 어떤 도움이라도 좋을 것입니다.
답변1
당신은 다음과 같은 질문에 관심이 있을 수 있습니다.태그 다시 쓰기, 여기에는 문제의 다양한 변형이 포함되어 있기 때문입니다.
Apache 재작성 규칙:
RewriteRule ^(.*)$ /index.php/$1 [L]
전체 요청 URI를 에 추가합니다 /index.php
. ~ 안에nginx그만큼길URI(정규화된)는 다음에서 사용할 수 있습니다.$uri변하기 쉬운. 쿼리 인수도 필요한 경우 다음을 사용할 수 있습니다.$request_uri대신에.
따라서 재작성 규칙을 엄격하게 번역하면 다음과 같습니다.
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;
}
정규식 일치 대신 접두사 일치를 사용하고 있으므로 위치 deny
에 대한 지시문이 작동 하지 않습니다./(data|img)/
location ~ ^/(data|img)/ {
# Only one is required
deny all;
# return 404;
}
답변2
재작성을 위한 솔루션
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;
}
내가 한 일은 줄을 바꾸는 것뿐이었습니다. 크레딧리차드 스미스
덕분에표트르 P. 카르와스, 다른 솔루션의 경우 스크립트가 100% 호환되는 사람이 자체적으로 깨끗한 URL을 처리하는 데 도움이 될 수 있습니다.
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;
}
위의 해결 방법은 스크립트가 깨끗한 URL로 100% 작동하는 한 갈 수 있는 방법입니다. 여기서는 수백 개의 재작성 위치 블록을 넣을 필요가 없으며 nginx는 전체 요청 URI를 /index.php에 추가합니다. 이는 매우 흥미롭고 도움이 됩니다. 아마도 이것이 실제 솔루션일 것입니다. 그러나 제 경우에는 제 스크립트가 100이 아니었습니다. % 이것과 호환됩니다. 여전히 이것은 훌륭한 솔루션입니다.
폴더, 파일 접근 방지 솔루션
location ~ ^/(data|img)/ {
# Only one is required
deny all;
# return 404;
}
크레딧표트르 P. 카르와스지적한 바에 따르면, 이는 deny all
무언가에 의해 재정의되고 있었고, 클린 서버 차단 시 문제가 해결되었습니다. 또한 deny all;
또는 중 하나를 함께 사용하지 않도록 하십시오 return 404;
.