Przekierowanie z HTTP do HTTPS z PHP

107

Pracuję nad witryną koszyka na zakupy i chciałbym przekierować użytkownika na stronę HTTPS, kiedy wprowadza swoje dane rozliczeniowe i utrzymywać połączenie HTTPS dla następnych stron, dopóki się nie wyloguje.

Co muszę zainstalować na serwerze (używam Apache), aby to zrobić i jak można to przekierować z PHP?

Psyche
źródło

Odpowiedzi:

247

Spróbuj czegoś takiego (powinno działać dla Apache i IIS):

if (empty($_SERVER['HTTPS']) || $_SERVER['HTTPS'] === "off") {
    $location = 'https://' . $_SERVER['HTTP_HOST'] . $_SERVER['REQUEST_URI'];
    header('HTTP/1.1 301 Moved Permanently');
    header('Location: ' . $location);
    exit;
}
Raphael Michel
źródło
5
To nie zawsze działa. Próbowałem go użyć i nie było elementu „https” w tablicy $ _SERVER, przez co wyświetlał błąd „zbyt wiele przekierowań”. Musiałby użyć innej metody.
Usman Zaheer
5
Musiałem przetestować, if( $_SERVER['HTTPS'] == "off")aby ten kod działał. Myślę, że to dlatego, że korzystam z IIS, a nie Apache jak OP.
Nick Pickering
1
@NicholasPickering Jepp, zmienne $ _SERVER mogą się różnić w zależności od serwerów WWW.
Raphael Michel
6
Uwaga: die () lub exit () mogą być ważne, aby umieścić je po przekierowaniach nagłówka, aby zapobiec wykonywaniu reszty strony (i prawdopodobnie wysyłaniu dodatkowych informacji do klienta) (tj. Do hakerów lub przeglądarek, które mogą nie uwzględniać nagłówka).
dajon,
3
W zależności od środowiska / konfiguracji serwera może być konieczne użycie $ _SERVER ['HTTP_X_FORWARDED_PROTO'], aby sprawdzić http / https
David Meister
19

To dobry sposób na zrobienie tego:

<?php
if (!(isset($_SERVER['HTTPS']) && ($_SERVER['HTTPS'] == 'on' || 
   $_SERVER['HTTPS'] == 1) ||  
   isset($_SERVER['HTTP_X_FORWARDED_PROTO']) &&   
   $_SERVER['HTTP_X_FORWARDED_PROTO'] == 'https'))
{
   $redirect = 'https://' . $_SERVER['HTTP_HOST'] . $_SERVER['REQUEST_URI'];
   header('HTTP/1.1 301 Moved Permanently');
   header('Location: ' . $redirect);
   exit();
}
?>
Matiasg1982
źródło
1
działa dobrze ten oznaczony jako dobry zwróci przekierowanie zbyt wiele razy, przynajmniej w przeglądarce Chrome
Thomas J Younsi,
Warunek !(isset($_SERVER['HTTPS']) && ($_SERVER['HTTPS'] == 'on'zawsze będzie fałszywy, ponieważ jeśli ostatnia część jest prawdziwa, pierwsza będzie fałszywa.
Max
@Max: Nie rozumiem tego, co mówisz. Jeśli drugi warunek jest prawdziwy ($ _SERVER ['HTTPS'] == 'on'), to pierwszy warunek również będzie musiał być TRUE (oczywiście ta zmienna serwera jest ustawiona, ponieważ zawiera wartość!)
OMA
7

Przekierowanie z HTTP do HTTPS z PHP w IIS

Miałem problem z przekierowaniem do HTTPS do pracy na serwerze Windows, na którym działa wersja 6 MS Internet Information Services (IIS) . Jestem bardziej przyzwyczajony do pracy z Apache na hoście z systemem Linux, więc zwróciłem się o pomoc do Internetu i było to najwyżej ocenione pytanie dotyczące przepełnienia stosu, gdy szukałem „przekierowania php http na https” . Jednak wybrana odpowiedź nie działa dla mnie.

Po kilku próbach i błędach odkryłem, że w przypadku usług IIS $_SERVER['HTTPS']jest ustawiony na offpołączenia inne niż TLS. Pomyślałem, że poniższy kod powinien pomóc innym użytkownikom IIS, którzy trafią na to pytanie za pośrednictwem wyszukiwarki.

<?php
if (! isset($_SERVER['HTTPS']) or $_SERVER['HTTPS'] == 'off' ) {
    $redirect_url = "https://" . $_SERVER['HTTP_HOST'] . $_SERVER['REQUEST_URI'];
    header("Location: $redirect_url");
    exit();
}
?>

Edycja : z innej odpowiedzi Stack Overflow prostszym rozwiązaniem jest sprawdzenie if($_SERVER["HTTPS"] != "on").

Anthony Geoghegan
źródło
13
@JakeSylvestre Fair wystarczająco. Biorąc pod uwagę, że to pytanie nie jest oznaczone jako apache, opublikowałem tę odpowiedź z korzyścią dla innych użytkowników IIS (podobnie jak w sytuacji, w której byłem), którzy mogą natknąć się na tę stronę za pośrednictwem wyszukiwarki. Zgadzam się z poglądem, że odpowiedzi służą całemu społeczeństwu, a nie tylko PO.
Anthony Geoghegan
6

Zawsze możesz użyć

header('Location: https://www.domain.com/cart_save/');

aby przekierować do adresu URL zapisu.

Ale poleciłbym to zrobić przez .htaccess i zasady przepisywania Apache.

powtac
źródło
13
Zawsze zalecałbym sprawdzenie $ _SERVER ['HTTPS'] przed przekierowaniem.
Raphael Michel
$ _SERVER ['HTTPS'] nie zawsze jest ustawione, ale warto to sprawdzić wcześniej. Dlatego polecam to zrobić z użyteczną regułą przepisywania w Apache, która przekierowuje tylko wtedy, gdy nie jest na HTTPS.
powtac
Chociaż Apache zaleca, aby nie używać dodatkowego pliku .htaccess (ponieważ spowalnia), ale użyć reguł przepisywania wewnątrz * .conf Apache.
powtac
1

Na moim serwerze łodygi fasoli AWS nie widzę zmiennej $ _SERVER ['HTTPS']. Widzę $ _SERVER ['HTTP_X_FORWARDED_PROTO'], które może mieć wartość „http” lub „https”, więc jeśli hostujesz w AWS, użyj tego:

if ($_SERVER['HTTP_HOST'] != 'localhost' and $_SERVER['HTTP_X_FORWARDED_PROTO'] != "https") {
    $location = 'https://' . $_SERVER['HTTP_HOST'] . $_SERVER['REQUEST_URI'];
    header('HTTP/1.1 301 Moved Permanently');
    header('Location: ' . $location);
    exit;
}
feniks
źródło