Làm cách nào tôi có thể buộc SSL / https bằng cách sử dụng trang .htaccess và mod_rewrite cụ thể trong PHP.
Làm cách nào tôi có thể buộc SSL / https bằng cách sử dụng trang .htaccess và mod_rewrite cụ thể trong PHP.
Câu trả lời:
Đối với Apache, bạn có thể sử dụng mod_ssl
để buộc SSL bằng SSLRequireSSL Directive
:
Lệnh này cấm truy cập trừ khi HTTP qua SSL (tức là HTTPS) được bật cho kết nối hiện tại. Điều này rất tiện dụng bên trong máy chủ hoặc thư mục ảo hỗ trợ SSL để bảo vệ chống lại các lỗi cấu hình làm lộ ra những thứ cần được bảo vệ. Khi có lệnh này, tất cả các yêu cầu đều bị từ chối không sử dụng SSL.
Điều này sẽ không làm chuyển hướng đến https mặc dù. Để chuyển hướng, hãy thử cách sau với mod_rewrite
trong tệp .htaccess của bạn
RewriteEngine On
RewriteCond %{HTTPS} !=on
RewriteRule ^ https://%{HTTP_HOST}%{REQUEST_URI} [L,R=301]
hoặc bất kỳ phương pháp khác nhau được đưa ra tại
Bạn cũng có thể giải quyết vấn đề này từ bên trong PHP trong trường hợp nhà cung cấp của bạn đã vô hiệu hóa .htaccess (điều này khó xảy ra vì bạn đã yêu cầu, nhưng dù sao đi nữa)
if (!isset($_SERVER['HTTPS']) || $_SERVER['HTTPS'] !== 'on') {
if(!headers_sent()) {
header("Status: 301 Moved Permanently");
header(sprintf(
'Location: https://%s%s',
$_SERVER['HTTP_HOST'],
$_SERVER['REQUEST_URI']
));
exit();
}
}
%{HTTP:X-Forwarded-Proto}
hoặc %{HTTP:X-Real-Port}
các biến để kiểm tra xem SSL có được bật hay không.
RewriteRule <input-pattern> <output-url>
. Do đó, không gian cần phải ở đó và người duy nhất ^
chỉ nói "khớp tất cả các URL đầu vào".
Tôi tìm thấy một mod_rewrite
giải pháp hoạt động tốt cho cả máy chủ proxy và máy chủ không được cung cấp.
Nếu bạn đang sử dụng CloudFlare, AWS Elastic Load Balance, Heroku, OpenShift hoặc bất kỳ giải pháp Cloud / PaaS nào khác và bạn đang gặp phải các vòng chuyển hướng với các chuyển hướng HTTPS bình thường, thay vào đó hãy thử đoạn trích sau.
RewriteEngine On
# If we receive a forwarded http request from a proxy...
RewriteCond %{HTTP:X-Forwarded-Proto} =http [OR]
# ...or just a plain old http request directly from the client
RewriteCond %{HTTP:X-Forwarded-Proto} =""
RewriteCond %{HTTPS} !=on
# Redirect to https version
RewriteRule ^ https://%{HTTP_HOST}%{REQUEST_URI} [L,R=301]
Mượn trực tiếp từ câu trả lời rất toàn diện của Gordon, tôi lưu ý rằng câu hỏi của bạn đề cập đến việc cụ thể theo trang trong việc buộc các kết nối HTTPS / SSL.
function forceHTTPS(){
$httpsURL = 'https://'.$_SERVER['HTTP_HOST'].$_SERVER['REQUEST_URI'];
if( count( $_POST )>0 )
die( 'Page should be accessed with HTTPS, but a POST Submission has been sent here. Adjust the form to point to '.$httpsURL );
if( !isset( $_SERVER['HTTPS'] ) || $_SERVER['HTTPS']!=='on' ){
if( !headers_sent() ){
header( "Status: 301 Moved Permanently" );
header( "Location: $httpsURL" );
exit();
}else{
die( '<script type="javascript">document.location.href="'.$httpsURL.'";</script>' );
}
}
}
Sau đó, gần với đầu của các trang mà bạn muốn buộc kết nối qua PHP, bạn có thể require()
một tệp tập trung có chứa các chức năng tùy chỉnh này (và bất kỳ trang nào khác), sau đó chỉ cần chạy forceHTTPS()
chức năng.
Tôi đã không thực hiện loại giải pháp này một cách cá nhân (tôi có xu hướng sử dụng giải pháp PHP, như cách đơn giản ở trên, vì nó đơn giản), nhưng ít nhất sau đây có thể là một khởi đầu tốt.
RewriteEngine on
# Check for POST Submission
RewriteCond %{REQUEST_METHOD} !^POST$
# Forcing HTTPS
RewriteCond %{HTTPS} !=on [OR]
RewriteCond %{SERVER_PORT} 80
# Pages to Apply
RewriteCond %{REQUEST_URI} ^something_secure [OR]
RewriteCond %{REQUEST_URI} ^something_else_secure
RewriteRule .* https://%{SERVER_NAME}%{REQUEST_URI} [R=301,L]
# Forcing HTTP
RewriteCond %{HTTPS} =on [OR]
RewriteCond %{SERVER_PORT} 443
# Pages to Apply
RewriteCond %{REQUEST_URI} ^something_public [OR]
RewriteCond %{REQUEST_URI} ^something_else_public
RewriteRule .* http://%{SERVER_NAME}%{REQUEST_URI} [R=301,L]
RewriteCond %{REQUEST_METHOD} !^POST$
?
RewriteCond %{REQUEST_METHOD} !^POST$
này sẽ ngăn việc gửi POST bị ảnh hưởng bởi các chuyển hướng này.
Mod-viết lại giải pháp dựa trên:
Sử dụng mã sau trong htaccess sẽ tự động chuyển tiếp tất cả các yêu cầu http sang https.
RewriteEngine on
RewriteCond %{HTTPS}::%{HTTP_HOST} ^off::(?:www\.)?(.+)$
RewriteRule ^ https://www.%1%{REQUEST_URI} [NE,L,R]
Điều này sẽ chuyển hướng các yêu cầu không phải www và www http của bạn sang phiên bản www của https.
Một giải pháp khác (Apache 2.4 *)
RewriteEngine on
RewriteCond %{REQUEST_SCHEME}::%{HTTP_HOST} ^http::(?:www\.)?(.+)$
RewriteRule ^ https://www.%1%{REQUEST_URI} [NE,L,R]
Điều này không hoạt động trên các phiên bản thấp hơn của apache vì biến% {REQUEST_SCHEME} đã được thêm vào mod-viết lại từ 2.4.
Tôi chỉ muốn chỉ ra rằng Apache có các quy tắc kế thừa tồi tệ nhất khi sử dụng nhiều tệp .htaccess trên độ sâu thư mục. Hai cạm bẫy chính:
RewriteOptions InheritDownBefore
(hoặc tương tự) để thay đổi điều này. (xem câu hỏi)Điều này có nghĩa là giải pháp toàn cầu gợi ý trên Apache Wiki không không có tác dụng nếu bạn sử dụng bất kỳ tập tin .htaccess khác trong thư mục con. Tôi đã viết một phiên bản sửa đổi mà:
RewriteEngine On
# This will enable the Rewrite capabilities
RewriteOptions InheritDownBefore
# This prevents the rule from being overrided by .htaccess files in subdirectories.
RewriteCond %{HTTPS} !=on
# This checks to make sure the connection is not already HTTPS
RewriteRule ^ https://%{SERVER_NAME}%{REQUEST_URI} [QSA,R,L]
# This rule will redirect users from their original location, to the same location but using HTTPS.
# i.e. http://www.example.com/foo/ to https://www.example.com/foo/
Đơn giản và dễ dàng, chỉ cần thêm sau
RewriteEngine On
RewriteCond %{HTTPS} off
RewriteRule ^(.*)$ https://%{HTTP_HOST}%{REQUEST_URI} [L,R=301]
Đơn giản
RewriteEngine on
RewriteCond %{HTTP_HOST} ^(www\.example\.com)(:80)? [NC]
RewriteRule ^(.*) https://example.com/$1 [R=301,L]
order deny,allow
thay thế url của bạn bằng example.com
chỉ cần buộc SSL với Apache .htaccess bạn có thể sử dụng
SSLOptions +StrictRequire
SSLRequireSSL
để chuyển hướng câu trả lời trên là chính xác
Hãy thử mã này, nó sẽ hoạt động cho tất cả các phiên bản URL như
RewriteCond %{HTTPS} off
RewriteCond %{HTTPS_HOST} !^www.website.com$ [NC]
RewriteRule ^(.*)$ https://www.website.com/$1 [L,R=301]