ฉันจะบังคับให้ SSL / https ใช้หน้า htaccess และ mod_rewrite เฉพาะใน PHP ได้อย่างไร
ฉันจะบังคับให้ SSL / https ใช้หน้า htaccess และ mod_rewrite เฉพาะใน PHP ได้อย่างไร
คำตอบ:
สำหรับ Apache คุณสามารถใช้mod_ssl
บังคับ SSL กับSSLRequireSSL Directive
:
คำสั่งนี้ห้ามการเข้าถึงยกเว้นว่า HTTP ผ่าน SSL (เช่น HTTPS) เปิดใช้งานสำหรับการเชื่อมต่อปัจจุบัน สิ่งนี้มีประโยชน์มากภายในโฮสต์หรือไดเรกทอรีเสมือนที่เปิดใช้งาน SSL เพื่อป้องกันข้อผิดพลาดในการกำหนดค่าที่เปิดเผยเนื้อหาที่ควรได้รับการป้องกัน เมื่อคำสั่งนี้แสดงการร้องขอทั้งหมดจะถูกปฏิเสธซึ่งไม่ได้ใช้ SSL
สิ่งนี้จะไม่เปลี่ยนเส้นทางไปยัง https แม้ว่า หากต้องการเปลี่ยนเส้นทางให้ลองทำตามด้วยmod_rewrite
ในไฟล์. htaccess ของคุณ
RewriteEngine On
RewriteCond %{HTTPS} !=on
RewriteRule ^ https://%{HTTP_HOST}%{REQUEST_URI} [L,R=301]
หรือวิธีการต่าง ๆ ที่ได้รับที่
คุณยังสามารถแก้ปัญหานี้ได้จากภายใน PHP ในกรณีที่ผู้ให้บริการของคุณปิดการใช้งาน. htaccess (ซึ่งไม่น่าจะเกิดขึ้นตั้งแต่ที่คุณขอมาแต่ทว่า)
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}
หรือ%{HTTP:X-Real-Port}
ตัวแปรเพื่อตรวจสอบว่า SSL เปิดอยู่หรือไม่
RewriteRule <input-pattern> <output-url>
ซ้ำไวยากรณ์คือ ดังนั้นพื้นที่จะต้องมีและ^
เพียงแค่พูดว่า "ตรงกับ URL อินพุตทั้งหมด"
ฉันพบmod_rewrite
วิธีแก้ปัญหาที่ทำงานได้ดีสำหรับเซิร์ฟเวอร์ทั้งที่ใช้งานร่วมและที่ไม่ได้ใช้งาน
หากคุณใช้CloudFlare, AWS Elastic Load Balancing, Heroku, OpenShiftหรือโซลูชัน Cloud / PaaS อื่น ๆ และคุณประสบปัญหาการเปลี่ยนเส้นทางโดยใช้การเปลี่ยนเส้นทาง HTTPS ปกติให้ลองใช้ตัวอย่างต่อไปนี้แทน
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]
การยืมโดยตรงจากคำตอบที่ครอบคลุมมากของกอร์ดอนฉันทราบว่าคำถามของคุณระบุว่าเป็นหน้าเฉพาะในการบังคับใช้การเชื่อมต่อ 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>' );
}
}
}
จากนั้นใกล้กับส่วนบนของหน้าเหล่านี้ที่คุณต้องการบังคับให้เชื่อมต่อผ่าน PHP คุณสามารถrequire()
ใช้ไฟล์ส่วนกลางที่มีฟังก์ชั่นที่กำหนดเองนี้ (และอื่น ๆ ) แล้วเรียกใช้forceHTTPS()
ฟังก์ชัน
ฉันยังไม่ได้ใช้โซลูชันประเภทนี้เป็นการส่วนตัว (ฉันมักจะใช้โซลูชัน PHP เช่นเดียวกับข้างต้นเพราะเป็นเรื่องง่าย) แต่อย่างน้อยอาจเป็นการเริ่มต้นที่ดี
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$
ควรป้องกันการส่ง POST ไม่ให้ได้รับผลกระทบจากการเปลี่ยนเส้นทางเหล่านี้
Mod-rewrite based solution:
การใช้รหัสต่อไปนี้ใน htaccess จะส่งต่อคำร้องขอ http ทั้งหมดไปที่ https โดยอัตโนมัติ
RewriteEngine on
RewriteCond %{HTTPS}::%{HTTP_HOST} ^off::(?:www\.)?(.+)$
RewriteRule ^ https://www.%1%{REQUEST_URI} [NE,L,R]
สิ่งนี้จะเปลี่ยนเส้นทางคำขอที่ไม่ใช่ wwwและwww http ไปยังรุ่นwwwของ https
โซลูชันอื่น (Apache 2.4 *)
RewriteEngine on
RewriteCond %{REQUEST_SCHEME}::%{HTTP_HOST} ^http::(?:www\.)?(.+)$
RewriteRule ^ https://www.%1%{REQUEST_URI} [NE,L,R]
สิ่งนี้ใช้ไม่ได้กับ apache รุ่นที่ต่ำกว่าเนื่องจากมีการเพิ่มตัวแปร% {REQUEST_SCHEME} ลงใน mod-rewrite ตั้งแต่ 2.4
ฉันแค่อยากจะชี้ให้เห็นว่า Apache มีกฎการรับมรดกที่เลวร้ายที่สุดเมื่อใช้ไฟล์. htaccess หลายไฟล์ในระดับความลึกของไดเรกทอรี ข้อผิดพลาดที่สำคัญสองประการ:
RewriteOptions InheritDownBefore
คำสั่ง (หรือคล้ายกัน) เพื่อเปลี่ยนสิ่งนี้ (ดูคำถาม)ที่นี้หมายถึงการแก้ปัญหาโลกปัญหาในApache วิกิพีเดียไม่ไม่ทำงานถ้าคุณใช้ htaccess ไฟล์อื่น ๆ ในไดเรกทอรีย่อย ฉันเขียนเวอร์ชันดัดแปลงที่ทำ:
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/
ง่ายและสะดวกเพียงเพิ่มสิ่งต่อไปนี้
RewriteEngine On
RewriteCond %{HTTPS} off
RewriteRule ^(.*)$ https://%{HTTP_HOST}%{REQUEST_URI} [L,R=301]
รหัสนี้ใช้ได้สำหรับฉัน
RewriteEngine On
RewriteBase /
RewriteCond %{HTTP:X-HTTPS} !1
RewriteRule ^(.*)$ https://%{HTTP_HOST}/$1 [R=301,L]
ง่าย ๆ :
RewriteEngine on
RewriteCond %{HTTP_HOST} ^(www\.example\.com)(:80)? [NC]
RewriteRule ^(.*) https://example.com/$1 [R=301,L]
order deny,allow
แทนที่ URL ของคุณด้วย example.com
เพียงแค่บังคับให้ SSL กับ Apache .htaccess คุณสามารถใช้ได้
SSLOptions +StrictRequire
SSLRequireSSL
สำหรับการเปลี่ยนเส้นทางคำตอบข้างต้นถูกต้อง
ลองใช้รหัสนี้มันจะใช้ได้กับทุก URL เช่น
RewriteCond %{HTTPS} off
RewriteCond %{HTTPS_HOST} !^www.website.com$ [NC]
RewriteRule ^(.*)$ https://www.website.com/$1 [L,R=301]