Widziałem wiele samouczków online, które mówią, że musisz sprawdzić, $_SERVER['HTTPS']
czy serwer jest połączony z HTTPS. Mój problem polega na tym, że na niektórych serwerach, których używam, $_SERVER['HTTPS']
jest niezdefiniowana zmienna, która powoduje błąd. Czy istnieje inna zmienna, którą mogę sprawdzić i którą zawsze należy zdefiniować?
Żeby było jasne, obecnie używam tego kodu, aby rozwiązać, czy jest to połączenie HTTPS:
if(isset($_SERVER['HTTPS'])) {
if ($_SERVER['HTTPS'] == "on") {
$secure_connection = true;
}
}
Secure
plików cookie. Uważaj jednak na gotchas.Odpowiedzi:
Powinno to zawsze działać, nawet gdy
$_SERVER['HTTPS']
jest niezdefiniowane:Kod jest zgodny z IIS.
Z dokumentacji PHP.net i komentarzy użytkowników :
Ponadto serwery Apache 1.x (i uszkodzone instalacje) mogły nie zostać
$_SERVER['HTTPS']
zdefiniowane, nawet jeśli łączą się bezpiecznie. Chociaż nie jest to gwarantowane, połączenia na porcie 443 są, z reguły , przy użyciu bezpiecznych gniazd , stąd dodatkowe sprawdzenie portu.Uwaga dodatkowa: jeśli istnieje moduł równoważenia obciążenia między klientem a serwerem, ten kod nie testuje połączenia między klientem a modułem równoważenia obciążenia, ale połączenie między modułem równoważenia obciążenia a serwerem. Aby przetestować poprzednie połączenie, musisz przetestować przy użyciu
HTTP_X_FORWARDED_PROTO
nagłówka, ale jest to o wiele bardziej skomplikowane; zobacz najnowsze komentarze poniżej tej odpowiedzi.źródło
getservbyname()
jest jedynie odniesieniem, a nie rzeczywistością i nie gwarantuje w żaden sposób, że HTTPS działa na porcie 443.$_SERVER['SERVER_PORT'] !== 443
musiałem rzucić$_SERVER['SERVER_PORT]
na liczbę całkowitą taką:intval($_SERVER['SERVER_PORT]) !== 443
strtolower($_SERVER['HTTPS']) !== 'off'
załatwił sprawę.Moje rozwiązanie (ponieważ standardowe warunki [$ _SERVER ['HTTPS'] == 'on'] nie działają na serwerach za modułem równoważenia obciążenia):
HTTP_X_FORWARDED_PROTO: de facto standard do identyfikacji protokołu źródłowego żądania HTTP, ponieważ zwrotny serwer proxy (moduł równoważenia obciążenia) może komunikować się z serwerem WWW za pomocą protokołu HTTP, nawet jeśli żądanie do zwrotnego serwera proxy to HTTPS http: //en.wikipedia. org / wiki / List_of_HTTP_header_fields # Common_non-standard_request_headers
źródło
Chacha, zgodnie z dokumentacją PHP: „Ustaw na niepustą wartość, jeśli skrypt był sprawdzany za pomocą protokołu HTTPS”. Tak więc twoja instrukcja if zwróci false w wielu przypadkach, gdy HTTPS jest rzeczywiście włączony. Będziesz chciał sprawdzić, czy
$_SERVER['HTTPS']
istnieje i nie jest pusty. W przypadkach, gdy HTTPS nie jest ustawiony poprawnie dla danego serwera, możesz spróbować sprawdzić, czy$_SERVER['SERVER_PORT'] == 443
.Pamiętaj jednak, że niektóre serwery również będą
$_SERVER['HTTPS']
miały niepustą wartość, więc sprawdź również tę zmienną.Odniesienie: Dokumentacja
$_SERVER
i$HTTP_SERVER_VARS
[przestarzałe]źródło
HTTP_X_FORWARDED_PROTO
lubHTTP_X_FORWARDED_SSL
też.(((isset($_SERVER['HTTPS'])) && (strtolower($_SERVER['HTTPS']) == 'on')) || ((isset($_SERVER['HTTP_X_FORWARDED_PROTO'])) && (strtolower($_SERVER['HTTP_X_FORWARDED_PROTO']) == 'https')))
który w ogóle nie obejmuje sprawdzenia portu. Nie krępuj się dodać. :-)SetEnvIf X-Forwarded-SSL on HTTPS=on
. Ale to nie zadziała,REQUEST_SCHEME
dlatego php wydaje się być lepszy w użyciu$_SERVER['HTTPS']
Działa to również wtedy, gdy nie
$_SERVER['HTTPS']
jest zdefiniowaneźródło
$_SERVER['HTTPS']
jeszcze nie zdefiniowano https. Co ty na to ?SERVER_PORT
jest zdefiniowany zawsze, który rozwiązuje nieokreślony problemHTTPS
Właśnie miałem problem z uruchomieniem serwera za pomocą Apache mod_ssl, ale phpinfo () i var_dump ($ _SERVER) pokazały, że PHP wciąż myśli, że jestem na porcie 80.
Oto moje obejście dla każdego, kto ma ten sam problem ...
Linia warta odnotowania to linia SetEnv. Mając to na swoim miejscu i po ponownym uruchomieniu, powinieneś mieć zmienną środowiskową HTTPS, o której zawsze marzyłeś
źródło
Tworzenie własnej funkcji na podstawie czytania wszystkich poprzednich postów:
źródło
Jeśli korzystasz z Apache, zawsze możesz liczyć
aby zweryfikować schemat żądanego adresu URL. Ale, jak wspomniano w innych odpowiedziach, rozważne jest sprawdzenie innych parametrów przed założeniem, że SSL jest rzeczywiście używany.
źródło
PRAWDZIWA odpowiedź: gotowy do kopiowania i wklejenia do skryptu [config]
$pv_URIprotocol
jest teraz poprawny i gotowy do użycia; przykładem$site=$pv_URIprotocol.$_SERVER["SERVER_NAME"]
. Oczywiście ciąg można również zastąpić PRAWDĄ i FAŁSZ. PV oznacza zmienną PortalPress, ponieważ jest to bezpośrednia kopia-wklej, która zawsze będzie działać. Ten kawałek można wykorzystać w skrypcie produkcyjnym.źródło
Nie sądzę, aby dodanie portu było dobrym pomysłem - szczególnie, gdy masz wiele serwerów z różnymi kompilacjami. to po prostu dodaje jeszcze jedną rzecz do zapamiętania, aby zmienić. patrząc na dokumenty uważam, że ostatnia linia kaiserów jest całkiem dobra, więc:
wydaje się idealnie.
źródło
Jedyną niezawodną metodą jest ta opisana przez Igora M.
Zastanów się: Używasz nginx z fastcgi, domyślnie (debian, ubuntu) fastgi_params zawiera dyrektywę:
fastcgi_param HTTPS $ https;
jeśli NIE używasz protokołu SSL, zostaje on przetłumaczony jako pusta wartość, a nie „wyłączony”, a nie 0, a ty jesteś skazany.
http://unpec.blogspot.cz/2013/01/nette-nginx-php-fpm-redirect.html
źródło
Uważam, że te parametry są również akceptowalne i bardziej prawdopodobne jest, że nie mają fałszywych trafień podczas przełączania serwerów sieciowych.
$ _SERVER ['HTTPS_SERVER_SUBJECT']
źródło
Najkrótsza droga, z której korzystam:
Jeśli używany jest protokół https, to $ secure_connection jest prawdziwe.
źródło
echo (!empty($_SERVER['HTTPS'])?'https':'http');
daje cihttp
lubhttps
(!empty($_SERVER['HTTPS']) && $_SERVER['HTTPS'] !== 'off')
Możesz sprawdzić,
$_SERVER['SERVER_PORT']
ponieważ SSL zwykle działa na porcie 443, ale nie jest to niezawodne.źródło
Co o tym sądzisz?
źródło
Na moim serwerze (Ubuntu 14.10, Apache 2.4, php 5.5) zmienna
$_SERVER['HTTPS']
nie jest ustawiona, gdy skrypt php jest ładowany przez https. Nie wiem co jest nie tak. Ale następujące wiersze w.htaccess
pliku rozwiązują ten problem:źródło
Oto funkcja wielokrotnego użytku, z której korzystam od dłuższego czasu. HTH.
Uwaga: Wartość HTTPS_PORT (która jest stałą niestandardową w moim kodzie) może się różnić w zależności od środowiska, na przykład może wynosić 443 lub 81.
źródło
tylko dla zainteresowania, chrom kanarek w tej chwili wysyła
do serwera, a w zależności od konfiguracji serwera może oznaczać, że otrzymasz następujące informacje
To zepsuło naszą aplikację, ponieważ testowaliśmy, czy jest włączona, co oczywiście nie jest. W tej chwili wydaje się, że robi to tylko kanarek chromowany, ale warto zauważyć, że rzeczy z kanarka zwykle lądują w „normalnym” chromie chwilę później.
źródło
Jeśli użyjesz nginx jako systemu równoważenia obciążenia, sprawdź $ _SERVER ['HTTP_HTTPS'] == 1 inne kontrole nie powiodą się dla ssl.
źródło
Kod sprawdza wszystko, co możliwe i działa również na serwerze internetowym IIS. Chrome od wersji 44 nie ustawia nagłówka HTTP: 1, więc sprawdzanie HTTP_HTTPS jest OK. Jeśli ten kod nie jest zgodny z https, oznacza to, że twój serwer WWW lub serwer proxy jest źle skonfigurowany. Sam Apache ustawia poprawnie flagę HTTPS, ale może wystąpić problem przy korzystaniu z proxy (np. Nginx). Musisz ustawić nagłówek w wirtualnym hoście nginx https
i użyj jakiegoś modułu Apache, aby poprawnie ustawić flagę HTTPS, szukając X-HTTPS z serwera proxy. Wyszukaj mod_fakessl, mod_rpaf itp.
źródło
Jeśli używasz modułu równoważenia obciążenia Incapsula, musisz użyć IRule, aby wygenerować niestandardowy nagłówek dla swojego serwera. Utworzyłem nagłówek HTTP_X_FORWARDED_PROTO, który jest równy „http”, jeśli port jest ustawiony na 80, i „https”, jeśli jest równy 443.
źródło
Dodałbym globalny filtr, aby upewnić się, że wszystko, co sprawdzam, jest prawidłowe;
źródło
Mam okazję pójść o krok dalej i ustalić, czy witryna, z którą się łączę, obsługuje protokół SSL (jeden projekt pyta użytkownika o jego adres URL i musimy zweryfikować, czy zainstalował nasz pakiet API na stronie http lub https).
Oto funkcja, której używam - po prostu wywołaj adres URL za pomocą cURL, aby sprawdzić, czy https działa!
Jest to najbardziej niezawodny sposób, który znalazłem, aby nie tylko dowiedzieć się, JEŻELI używasz protokołu https (jak pyta pytanie), ale jeśli MUSISZ (a nawet POWINIENI) używać protokołu https.
UWAGA: jest możliwe (choć mało prawdopodobne ...), że witryna może mieć różne strony http i https (więc jeśli powiedziano ci, aby używać http, być może nie musisz zmieniać ..) Zdecydowana większość witryn są takie same i prawdopodobnie powinien sam Cię przekierować, ale ta dodatkowa kontrola ma swoje zastosowanie (z pewnością, jak powiedziałem, w projekcie, w którym użytkownik wprowadza informacje o swojej witrynie i chcesz się upewnić po stronie serwera)
źródło
W ten sposób znajduję rozwiązanie tego
źródło
Użyłem tutaj głównej sugestii i zirytowało mnie „PHP Notice” w logach, gdy nie ustawiono HTTPS. Można tego uniknąć, używając operatora zerowania koalescencji „??”:
(Uwaga: niedostępne przed php v7)
źródło
Zgodnie z postem hobodave'a: „Ustaw na niepustą wartość, jeśli skrypt był sprawdzany za pomocą protokołu HTTPS”.
źródło
(!empty($_SERVER['HTTPS']) && $_SERVER['HTTPS'] !== 'off')