Wątpliwy rejestr php. Tworzymy niesamowicie prosty system rejestracji w PHP i MySQL

Wątpliwy rejestr php. Tworzymy niesamowicie prosty system rejestracji w PHP i MySQL

21.11.2021

Aby podzielić odwiedzających witrynę na określone grupy, w witrynie należy zainstalować mały system rejestracja php... W ten sposób warunkowo dzielisz odwiedzających na dwie grupy po prostu przypadkowych użytkowników i na bardziej uprzywilejowaną grupę użytkowników, którym dostarczasz bardziej wartościowe informacje.

W większości przypadków stosowany jest bardziej uproszczony system rejestracji, który jest napisany w php w jednym pliku. rejestr.php.

Trochę więc dygresja, a teraz przyjrzymy się bliżej plikowi rejestracyjnemu.

Plik Register.php

Aby nie zabierało Ci to dużo czasu, stworzymy system, który będzie gromadził użytkowników, pobierając od nich minimalne dane kontaktowe. W takim przypadku wprowadzimy wszystko do bazy mysql. Dla jak największej szybkości bazy danych stworzymy tabelę użytkowników w formacie MyISAM oraz w kodowaniu utf-8.

Notatka! Wszystkie skrypty muszą być zawsze napisane w tym samym kodowaniu. Wszystkie pliki witryny i baza danych MySql muszą być w tym samym kodowaniu. Najpopularniejsze kodowania to UTF-8 i Windows-1251.

Dlaczego musisz pisać wszystko w jednym kodowaniu, porozmawiamy później. Do tego czasu traktuj te informacje jako najściślejszą praktyczną zasadę skryptowania, w przeciwnym razie wystąpią problemy ze skryptami w przyszłości. Oczywiście jest w porządku, ale po prostu marnujesz dużo czasu na szukanie błędów w skrypcie.

Jak będzie działał sam skrypt?

Chcemy wszystko uprościć i uzyskać szybkie rezultaty. Dlatego od użytkowników otrzymamy tylko login, e-mail i hasło. Aby chronić się przed robotami spamującymi, zainstalujemy małą captcha. W przeciwnym razie jakiś chłopak z Londynu napisze mały parser robota, który zapełni całą bazę fałszywymi użytkownikami w ciągu kilku minut i będzie się cieszył z jego geniuszu i bezkarności.

Oto sam skrypt. Wszystko jest napisane w jednym pliku rejestr.php:

! `; // czerwony znak zapytania $ sha = $ sh. "scripts / pro /"; // ścieżka do głównego folderu $ bg = `bgcolor =" # E1FFEB "`; // kolor tła linii?> Przykładowy skrypt rejestru register.php style.css "/>

W tym przypadku skrypt odnosi się do siebie. A jest to formularz i podmiot przetwarzający dane wprowadzone do formularza. Należy pamiętać, że plik jest skompresowany w archiwum zip i zawiera plik konfiguracyjny config.php, zrzut bazy danych użytkowników, plik zawierający funkcje pomocnicze.php, plik style.css oraz sam plik register.php. Istnieje również kilka plików odpowiedzialnych za działanie i generowanie symboli captcha.

Dzisiaj rozważymy wykorzystanie krytycznej luki 1day w popularnym CMS Joomla, która grzmiała w Internecie pod koniec października. Porozmawiamy o lukach z liczbami CVE-2016-8869, CVE-2016-8870 oraz CVE-2016-9081... Wszystkie trzy pochodzą z jednego kawałka kodu, który gnił w trzewiach frameworka przez pięć długich lat, czekając na swoją godzinę, aby się uwolnić i przynieść ze sobą chaos, zhakowane strony i łzy niewinnych użytkowników tej Joomla. Tylko najbardziej odważni i odważni deweloperzy, których oczy są czerwone od światła monitorów, a klawiatury zaśmiecone są okruchami chleba, byli w stanie rzucić wyzwanie szalejącym złym duchom i położyć głowy na ołtarzu poprawek.

OSTRZEŻENIE

Wszystkie informacje podane są wyłącznie w celach informacyjnych. Ani redakcja, ani autor nie ponoszą odpowiedzialności za ewentualne szkody wyrządzone przez materiały tego artykułu.

Jak to się wszystko zaczęło

6 października 2016 r. Demis Palma stworzył temat na Stack Exchange, w którym zapytał: dlaczego w rzeczywistości w Joomla w wersji 3.6 istnieją dwie metody rejestrowania użytkowników o tej samej nazwie register()? Pierwszy znajduje się w UsersControllerRegistration, a drugi w UsersControllerUser. Damis chciał wiedzieć, czy metoda UsersControllerUser :: register() jest gdzieś używana, czy jest to tylko ewolucyjny anachronizm pozostawiony po starej logice. Martwił go fakt, że nawet jeśli ta metoda nie została wykorzystana przez żaden widok, to i tak można ją wywołać z wygenerowanym żądaniem. Na co otrzymałem odpowiedź od dewelopera o nicku ioctopus, który potwierdził, że problem naprawdę istnieje. I wysłałem raport do programistów Joomla.

Kolejne wydarzenia rozwijały się w najszybszym tempie. 18 października programiści Joomla przyjmują raport od Damisa, który do tego czasu naszkicował PoC, aby umożliwić rejestrację użytkownika. Opublikował notatkę na swojej stronie internetowej, w której przedstawił problem, który znalazł, i swoje przemyślenia na ten temat. Tego samego dnia zostaje wydana nowa wersja Joomla 3.6.3, która nadal zawiera zagrożony kod.

Następnie Davide Tampellini rozwija błąd do stanu rejestracji nie zwykłego użytkownika, ale administratora. A już 21 października do zespołu bezpieczeństwa Joomla trafia nowa sprawa. Mówi już o eskalacji przywilejów. Tego samego dnia na stronie Joomla pojawiło się ogłoszenie, że we wtorek 25 października zostanie wydana kolejna wersja o numerze seryjnym 3.6.3, która naprawia krytyczną lukę w rdzeniu systemu.

25 października Joomla Security Strike Team znajduje ostatni problem, który jest tworzony przez fragment kodu odkryty przez Damisa. Następnie commit datowany na 21 października o niepozornej nazwie Przygotuj 3.6.4 Stabilne wydanie jest przesyłany do głównej gałęzi oficjalnego repozytorium Joomla, co naprawia niefortunny błąd.

Po tym ujawnieniu na spotkanie deweloperów przyłącza się wiele zainteresowanych osób - zaczynają oni odkręcać lukę i przygotowywać exploity.

27 października badacz Harry Roberts przesyła gotowy exploit do repozytorium Xiphos Research, który może przesłać plik PHP na serwer z podatnym CMS.

Detale

Skończyliśmy już z tłem, przejdźmy do najciekawszej części - analizy podatności. Jako wersję testową zainstalowałem Joomla 3.6.3, więc wszystkie numery linii będą odpowiednie dla tej konkretnej wersji. Wszystkie ścieżki do plików, które widzisz poniżej, zostaną wskazane w odniesieniu do katalogu głównego zainstalowanego CMS.

Dzięki znalezisku Damis Palmy wiemy, że istnieją dwie metody, które wykonują rejestrację użytkownika w systemie. Pierwszy jest używany przez CMS i znajduje się w pliku /components/com_users/controllers/registration.php:108. Drugi (ten, który musimy wywołać) znajduje się w /components/com_users/controllers/user.php:293. Przyjrzyjmy się temu bliżej.

286: / ** 287: * Metoda rejestracji użytkownika. 288: * 289: * @return boolean 290: * 291: * @od 1.6 292: * / 293: rejestr funkcji publicznych () 294: (295: JSession :: checkToken ("post") lub jexit (JText :: _ ("JINVALID_TOKEN")); ... 300: // Pobierz dane formularza 301: $ data = $ this-> input-> post-> get ("user", array(), "array");. .. 315: $ return = $ model-> validate ($ formularz, $ data); 316: 317: // Sprawdź błędy 318: if ($ return === false) 319: (... 345: / / Zakończ rejestrację.346: $ return = $ model-> register ($ dane);

Tutaj zostawiłem tylko ciekawe wersy. Pełną wersję podatnej metody można obejrzeć w repozytorium Joomla.

Zastanówmy się, co dzieje się podczas normalnej rejestracji użytkownika: jakie dane są przesyłane i jak są przetwarzane. Jeżeli rejestracja użytkownika jest włączona w ustawieniach, to formularz można znaleźć pod adresem http://joomla.local/index.php/component/users/?View = rejestracja.


Uzasadnione żądanie rejestracji użytkownika wygląda jak na poniższym zrzucie ekranu.


Komponent com_users odpowiada za pracę z użytkownikami. Zwróć uwagę na parametr zadania w żądaniu. Jest w formacie $ kontroler $ Metoda. Przyjrzyjmy się strukturze plików.

Nazwy skryptów w folderze kontrolerzy odpowiadają nazwom wywoływanych kontrolerów. Ponieważ nasze żądanie zawiera teraz $controller = „rejestracja”, plik zostanie nazwany rejestracja.php i jego rejestr () metoda.

Uwaga, pytanie: jak przekazać przetwarzanie rejestracji do luki w kodzie? Pewnie już zgadłeś. Nazwy podatnych i rzeczywistych metod są takie same (rejestr), więc wystarczy zmienić nazwę wywoływanego kontrolera. Gdzie znajduje się zagrożony kontroler? Zgadza się, w pliku użytkownik.php... Okazuje się, że kontroler $ = "użytkownik". Złożenie wszystkiego razem i uzyskanie zadania = user.register. Teraz żądanie rejestracji jest przetwarzane za pomocą potrzebnej metody.


Drugą rzeczą, którą musimy zrobić, to wysłać dane w odpowiednim formacie. Tutaj wszystko jest proste. Prawidłowy rejestr () oczekuje od nas tablicy o nazwie jform, w której przekazujemy dane do rejestracji - imię i nazwisko, login, hasło, mail (patrz zrzut ekranu z zapytaniem).

  • /components/com_users/controllers/registration.php: 124: // Pobierz dane użytkownika. 125: $ requestData = $ this-> input-> post-> get ("jform", array(), "array");

Nasz oddział pobiera te dane z tablicy o nazwie user.

  • /components/com_users/controllers/user.php: 301: // Pobierz dane formularza. 302: $ data = $ this-> input-> post-> get ("user", array(), "array");

Dlatego zmieniamy nazwy wszystkich parametrów w żądaniu z jfrom na user.

Naszym trzecim krokiem jest znalezienie prawidłowego tokena CSRF, ponieważ bez niego nie będzie rejestracji.

  • /components/com_users/controllers/user.php: 296: JSession :: checkToken („post”) lub jexit (JText :: _ („JINVALID_TOKEN”));

Wygląda jak hash MD5 i można go pobrać np. z formularza autoryzacji na stronie /index.php/component/users/?view=login.


Teraz możesz tworzyć użytkowników za pomocą wybranej metody. Jeśli wszystko się udało, to gratulacje - właśnie wykorzystałeś lukę CVE-2016-8870„Brak sprawdzenia uprawnień do rejestracji nowych użytkowników”.

Tak to wygląda w metodzie "working" register() z kontrolera UsersControllerRegistration:

  • /components/com_users/controllers/registration.php: 113: // Jeśli rejestracja jest wyłączona - Przekieruj na stronę logowania. 114: if (JComponentHelper :: getParams ("com_users") -> get ("allowUserRegistration") == 0) 115: (116: $ this-> setRedirect (JRoute :: _ ("index.php? Option = com_users & view = login ", false)); 117: 118: return false; 119 :)

I tak w wrażliwych:

  • /components/com_users/controllers/user.php:

Tak, nie ma mowy.

Aby zrozumieć drugi, znacznie poważniejszy problem, wyślijmy utworzone przez nas żądanie i prześledźmy, jak jest wykonywane w różnych częściach kodu. Oto fragment odpowiedzialny za weryfikację danych przesłanych przez użytkownika w działającej metodzie:

Kontynuacja jest dostępna tylko dla uczestników

Opcja 1. Dołącz do społeczności „strony”, aby przeczytać wszystkie materiały na stronie

Członkostwo w społeczności w określonym czasie otworzy dostęp do WSZYSTKICH materiałów hakerskich, zwiększy osobistą skumulowaną zniżkę i pozwoli na zgromadzenie profesjonalnego wyniku Xakep!

Jeśli chcesz udostępnić jedną z sekcji swojej witryny ograniczonemu, ale nieokreślonemu kręgowi osób, najłatwiej to zrobić, rejestrując i autoryzując użytkowników. Istnieje wiele sposobów uwierzytelniania użytkowników. Można używać zarówno narzędzi serwera WWW, jak i narzędzi języka programowania. Porozmawiamy o przypadku, w którym używane są sesje PHP.

Zapewne chciałbyś zobaczyć bardziej nowoczesny sposób tworzenia takiego kształtu. Wciąż mam kompletną, nowoczesną i aktualną prezentację, ale widać, że formularz opinii można zbudować przy użyciu technik obiektowych w PHP.

Najpierw omówmy wszystkie kroki, które podejmiemy dalej. Czego w ogóle potrzebujemy? Potrzebujemy skryptu, który zarejestruje użytkownika, autoryzuje użytkownika, przekieruje go gdzieś po autoryzacji. Będziemy też musieli stworzyć stronę, która będzie chroniona przed dostępem nieautoryzowanych użytkowników. W celu rejestracji i autoryzacji będziemy musieli utworzyć formularze HTML. Będziemy przechowywać informacje o zarejestrowanych użytkownikach w bazie danych. Oznacza to, że nadal potrzebujemy skryptu do połączenia z DBMS. Cała nasza praca będzie wykonywana przez funkcje, które sami napiszemy. Funkcje te zapiszemy w osobnym pliku.

Potrzebujemy więc następujących plików:

  • połączenie z DBMS;
  • funkcje niestandardowe;
  • upoważnienie;
  • rejestracja;
  • strona chroniona;
  • skrypt zamykający użytkownika;
  • skrypt sprawdzający status autoryzacji użytkownika;
  • arkusz stylów dla najprostszego projektu naszych stron.

Wszystko to byłoby bezcelowe, jeśli nie masz odpowiedniej tabeli w swojej bazie danych. Uruchom swoje narzędzie do zarządzania DBMS (PhpMyAdmin lub wiersz poleceń, w zależności od tego, co jest wygodniejsze) i uruchom w nim następujące zapytanie:

CREATE TABLE `users` (`id` int (11) NOT NULL AUTO_INCREMENT, `login` char (16) NOT NULL,` password` char (40) NOT NULL, `reg_date` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP, PRIMARY KEY (` id`)) ENGINE = MyISAM DOMYŚLNY ZESTAW ZNAKÓW = utf8 AUTO_INCREMENT = 1;

Nazwę nasze pliki skryptów w ten sposób (wszystkie będą w tym samym katalogu):

  • baza danych.php;
  • funkcje.php;
  • login.php;
  • rejestracja.php;
  • index.php;
  • wyloguj.php;
  • checkAuth.php;
  • styl.css.

Jestem pewien, że cel każdego z nich jest dla ciebie jasny. Zacznijmy od skryptu połączenia DBMS. Widziałeś to wcześniej. Po prostu zapisz kod tego skryptu w pliku o nazwie database.php. Funkcje niestandardowe zadeklarujemy w pliku functions.php. Jak to wszystko będzie działać? Nieautoryzowany użytkownik próbuje uzyskać dostęp do chronionego dokumentu index.php, system sprawdza, czy użytkownik jest autoryzowany, jeśli użytkownik nie jest autoryzowany, zostaje przekierowany na stronę autoryzacji. Na stronie autoryzacji użytkownik powinien zobaczyć formularz autoryzacji. Zróbmy to.

Autoryzacja użytkownika

Zarejestruj się.

Teraz musimy nadać naszemu kształtowi określony wygląd. Jednocześnie określimy zasady dla pozostałych elementów. Mam zamiar przekazać Ci pełną zawartość arkusza stylów, wyprzedzając samego siebie.

/ * plik style.css * / .row (margin-bottom: 10px; width: 220px;) .row label (display: block; font-weight: bold;) .row input.text (font-size: 1.2em; padding: 2px 5px;) .to_reg (rozmiar czcionki: 0.9em;).instrukcja (rozmiar czcionki: 0.8em; kolor: #aaaaaa; margines lewy: 2px; kursor: domyślnie;) .error (kolor: czerwony; margines lewy: 3px;)

Jeśli wszystko jest zrobione poprawnie, powinieneś mieć w swojej przeglądarce:

Oczywiście nie mamy jeszcze jednego zarejestrowanego użytkownika, a żeby się zalogować, musisz się zarejestrować. Zróbmy formularz rejestracyjny.

Rejestracja Użytkownika

" />

Zapewne zauważyłeś, że w kodzie HTML znajdują się zmienne PHP. Są to zawartość atrybutów pól tekstowych w formularzach, zawartość kontenerów do wyświetlania błędów. Ale nie zainicjalizowaliśmy tych zmiennych. Zróbmy to.

Rejestracja Użytkownika

" />
Nazwa użytkownika może zawierać tylko znaki łacińskie, cyfry, symbole „_”, „-”, „.”. Długość nazwy użytkownika musi wynosić co najmniej 4 znaki i nie więcej niż 16 znaków
W haśle można używać tylko znaków łacińskich, cyfr, symboli „_”, „!”, „(”, „)”. Hasło musi mieć co najmniej 6 znaków i nie dłuższe niż 16 znaków
Powtórz poprzednio wprowadzone hasło

Nie ma określonego parametru w atrybucie działania znacznika formularza. W takim przypadku po przesłaniu danych formularza zostaną one przetworzone w tym samym skrypcie, z którego zostały przesłane. Więc musimy napisać kod, który przetwarza dane formularza. Ale najpierw omówmy algorytm ich przetwarzania.

Pola loginu i hasła muszą być niepuste. Następnie musisz sprawdzić login pod kątem zgodności z wymaganiami. Hasło musi również spełniać opisane wymagania, a powtórzone hasło musi mu odpowiadać, a ponadto muszą być identyczne. Jeżeli którykolwiek z tych warunków nie jest spełniony, należy przerwać przetwarzanie danych formularza, w tablicy komunikatów o błędach wpisać odpowiednie powiadomienie i wyświetlić je użytkownikowi. Dla wygody użytkownika zapiszemy wpisany przez niego login (o ile go wskazał), wpisując jego wartość do tablicy $fields.

Jeśli wszystko jest w porządku, w oknie przeglądarki, odwołując się do dokumentu registration.php, powinieneś zobaczyć coś takiego:

Załóżmy teraz, że użytkownik klika przycisk rejestracji bez wypełniania pól formularza. Według naszego algorytmu login i hasło nie mogą być puste. Jeśli ten warunek nie jest spełniony, rejestracja nie jest możliwa. Pamiętajmy, że przetwarzanie danych formularza odbywa się w aktualnym skrypcie. Oznacza to, że musimy zmienić jego kod, dodając odpowiednie sprawdzenia. Niezwłocznie określimy następujące kontrole. W przypadku wprowadzenia loginu i hasła należy sprawdzić ich zgodność z określonymi wymaganiami. Aby sprawdzić login i hasło, utworzymy niestandardowe funkcje w pliku functions.php.

/ ** * functions.php * Plik z niestandardowymi funkcjami * / // Dołącz plik z parametrami do połączenia z DBMS require_once ("database.php"); // Sprawdzenie funkcji nazwy użytkownika checkLogin ($ str) (// Zainicjuj zmienną z możliwym komunikatem o błędzie $ error = ""; // Jeśli nie ma ciągu logowania, zwróć komunikat o błędzie if (! $ Str) ($ error = " Nie wpisałeś nazwy użytkownika "; zwróć błąd $ ;) / ** * Sprawdź nazwę użytkownika za pomocą wyrażeń regularnych * Login musi mieć co najmniej 4, nie dłuższy niż 16 znaków * Musi zawierać znaki łacińskie, cyfry, * może być znakami "_", "-", "." * / $ wzorzec = "/^ [-_.az\d ](4,16)$/i"; $ wynik = preg_match ($ wzorzec, $ str) ; // Jeśli sprawdzenie się nie powiedzie, zwróć komunikat o błędzie if (! $ Wynik) ($ error = "Nieprawidłowe znaki w nazwie użytkownika lub nazwa użytkownika jest za krótka (długa)"; zwróć $ error;) // Jeśli wszystko jest w porządku , return true return true;) // Sprawdź funkcję hasła użytkownika checkPassword ($ str) (// Zainicjuj zmienną z możliwym komunikatem o błędzie $ error = ""; // Jeśli nie ma pojawi się napis z loginem, zwróć komunikat o błędzie if (! $ str) ($ error = "Nie wpisałeś hasła"; zwróć błąd $; ) / ** * Sprawdź hasło użytkownika za pomocą wyrażeń regularnych * Hasło nie może być krótsze niż 6, nie dłuższe niż 16 znaków * Musi zawierać znaki łacińskie, cyfry, * może zawierać znaki "_", "!", " ( ",") "* / $ wzorzec =" /^ [_!)(.az\d *(6,16)$/i "; $ wynik = preg_match ($ wzorzec, $ str); // Jeśli sprawdzenie nie powiodło się, zwróć komunikat o błędzie if (! $ wynik) ($ error = "Nieprawidłowe znaki w haśle użytkownika lub hasło jest za krótkie (długie)"; return $ error;) // Jeśli wszystko jest w porządku, zwróć true return true ; )

Teraz musimy zmodyfikować plik registration.php, aby korzystał z zadeklarowanych przez nas funkcji. Dodamy warunek do skryptu, aby sprawdzić, czy przycisk rejestracji jest kliknięty. W tym warunku rozpoczyna się sprawdzanie loginu i haseł. Jeśli którakolwiek z kontroli się nie powiedzie, ponownie renderujemy formularz i wyświetlamy komunikat o błędzie. Jeśli nie ma błędów, rejestrujemy użytkownika, nie wyświetlamy już formularza rejestracyjnego, informujemy użytkownika o udanej rejestracji, a korzystając z funkcji nagłówka () przekierowujemy go do formularza autoryzacji.

Pomyślnie zarejestrowałeś się w systemie. Zostaniesz teraz przekierowany na stronę logowania. Jeśli tak się nie stało, przejdź do niego za pomocą bezpośredniego linku.

"; header (" Odśwież: 5; URL = login.php ");) // W przeciwnym razie poinformuj użytkownika o błędzie else ($ błędy [" full_error "] = $ reg;)))?> Rejestracja Użytkownika
" />
Nazwa użytkownika może zawierać tylko znaki łacińskie, cyfry, symbole „_”, „-”, „.”. Długość nazwy użytkownika musi wynosić co najmniej 4 znaki i nie więcej niż 16 znaków
W haśle można używać tylko znaków łacińskich, cyfr, symboli „_”, „!”, „(”, „)”. Hasło musi mieć co najmniej 6 znaków i nie dłuższe niż 16 znaków
Powtórz poprzednio wprowadzone hasło

Powinieneś zauważyć kolejną nową funkcję w skrypcie - rejestrację (). I jeszcze tego nie ogłosiliśmy. Zróbmy to.

// Rejestracja funkcji rejestracji użytkownika ($ login, $ hasło) (// Zainicjuj zmienną z możliwym komunikatem o błędzie $ error = ""; // Jeśli nie ma ciągu logowania, zwróć komunikat o błędzie if (! $ Login) ($ error = "Nie określono logowania"; zwróć błąd $;) elseif (! $ hasło) ($ error = "Nie określono hasła"; return $ error;) // Sprawdź, czy użytkownik jest już zarejestrowany // Połącz się z DBMS connect() ; // Napisz zapytanie $ sql = "SELECT` id` FROM `users` WHERE` login` = "". $ Login. "" "; // Wykonaj zapytanie do bazy danych $ query = mysql_query ($ sql) lub die ( ""); // Sprawdź liczbę użytkowników z tym loginem, jeśli jest przynajmniej jeden, // zwróć komunikat o błędzie if (mysql_num_rows ($ query)> 0) ($ error = "Użytkownik o podanym loginie jest już zarejestrowany"; zwróć błąd $;) // Jeśli nie ma takiego użytkownika, zarejestruj go // Napisz zapytanie $ sql = "INSERT INTO` users` (`id`,` login `, `hasło`) WARTOŚCI (NULL," ". $ login." "," ". $ hasło. "") "; // Wykonaj zapytanie do bazy danych $ query = mysql_query ($ sql) lub die ("

Nie można dodać użytkownika: ". Mysql_error ().". Wystąpił błąd w wierszu „. __LINE__.”

"); // Nie zapomnij odłączyć się od DBMS mysql_close (); // Zwróć wartość true, wskazującą na pomyślną rejestrację użytkownika, return true;)

Jeśli wszystko jest w porządku, Twój użytkownik zostanie zarejestrowany. Możesz przetestować formularz. Spróbuj zarejestrować użytkowników z tymi samymi loginami. Po udanej rejestracji użytkownik zostanie przekierowany do formularza autoryzacji. Wcześniej po prostu utworzyliśmy znacznik, aby wyświetlić ten formularz. Ponieważ w jego atrybucie action nie ma określonego parametru, dane przesłane przez formularz będą przetwarzane w tym samym skrypcie. Musimy więc napisać kod do przetworzenia i dodać go do dokumentu login.php.

Autoryzacja użytkownika

;">

Jeśli nie jesteś zarejestrowany w systemie, zarejestruj się.

Zapewne zauważyłeś, że w skrypcie autoryzacji mamy inną nieznaną nam funkcję - autoryzację (). Funkcja ta powinna autoryzować użytkownika po sprawdzeniu, czy w bazie danych jest zarejestrowany użytkownik o tej samej nazwie użytkownika i haśle. Jeśli taki użytkownik nie zostanie znaleziony, autoryzacja zostanie przerwana, a na ekranie pojawi się komunikat o niepowodzeniu. Jeśli sprawdzenie się powiedzie, funkcja autoryzacji () uruchomi sesję i zapisze do niej wartości nazwy użytkownika i hasła, poinformuje skrypt o powodzeniu autoryzacji, a skrypt przekieruje użytkownika na stronę chronionego zasobu.

/ ** * Funkcja autoryzacji użytkownika. * Autoryzacja użytkowników u nas zostanie przeprowadzona * przy użyciu sesji PHP. * / autoryzacja funkcji ($ login, $ hasło) (// Zainicjuj zmienną z możliwym komunikatem o błędzie $ error = ""; // Jeśli nie ma linii logowania, zwróć komunikat o błędzie if (! $ login) ($ error = " Nie określono logowania "; zwróć $ błąd;) elseif (! $ Hasło) ($ błąd =" Nie określono hasła "; zwróć $ błąd;) // Sprawdź, czy użytkownik jest już zarejestrowany // Połącz z DBMS connect ( // Musimy sprawdzić, czy wśród zarejestrowanych jest taki użytkownik // Ułożenie zapytania $ sql = "SELECT` id` FROM `users` WHERE` login` = "". $ Login. "" AND `password` =" ". $ Hasło . "" "; // Wykonaj zapytanie $ query = mysql_query ($ sql) lub die ("

Nie można wykonać zapytania: ". Mysql_error ().". Wystąpił błąd w wierszu „. __LINE__.”

"); // Jeśli nie ma użytkownika z takimi danymi, zwróć komunikat o błędzie if (mysql_num_rows ($ zapytanie) == 0) ($ error =" Użytkownik z określonymi danymi nie jest zarejestrowany "; return $ error;) // Jeśli użytkownik istnieje , uruchom sesję session_start ();// I wpisz w nim nazwę użytkownika i hasło // W tym celu używamy tablicy superglobalnej $ _SESSION $ _SESSION ["login"] = $ login; $ _SESSION [" password"] = $ hasło; // Nie zapomnij zamknąć połączenia z bazą danych mysql_close (); // Zwróć true w przypadku komunikatu o pomyślnej autoryzacji użytkownika, return true;)

Gdy użytkownik wchodzi na chronioną stronę, należy sprawdzić poprawność jego danych autoryzacyjnych. Do tego potrzebujemy jeszcze jednej niestandardowej funkcji. Nazwijmy to checkAuth (). Jego zadaniem będzie porównanie danych autoryzacyjnych użytkownika z tymi, które znajdują się w naszej bazie danych. Jeśli dane się nie zgadzają, użytkownik zostanie przekierowany na stronę autoryzacji.

Funkcja checkAuth ($ login, $ hasło) (// Jeśli nie ma nazwy użytkownika lub hasła, zwróć false if (! $ Login ||! $ Password) return false; // Sprawdź, czy taki użytkownik jest zarejestrowany // Połącz się z DBMS connect (); // Utwórz ciąg zapytania $ sql = "SELECT` id` FROM `users` WHERE` login` = "". $ Login. "" AND `password` =" ". $ Password." "" ; // Wykonaj zapytanie $ query = mysql_query ($ sql) lub die ("

Nie można wykonać zapytania: ". Mysql_error ().". Wystąpił błąd w wierszu „. __LINE__.”

"); // Jeśli nie ma użytkownika z takimi danymi, zwróć false; if (mysql_num_rows ($ zapytanie) == 0) (return false;) // Nie zapomnij zamknąć połączenia z bazą danych mysql_close (); // Inaczej , zwróć prawdę, zwróć prawdę;)

Teraz, gdy użytkownik znajduje się na bezpiecznej stronie, musimy wywołać funkcję sprawdzania poprawności danych autoryzacyjnych. Skrypt call i check umieścimy w osobnym pliku checkAuth.php i połączymy go ze stronami, które zostaną zamknięte dla publicznego dostępu.

/ ** * Skrypt do sprawdzania autoryzacji użytkowników * / // Rozpocznij sesję, z której wydobędziemy login i hasło // zalogowanych użytkowników session_start (); // Dołącz plik z funkcjami niestandardowymi require_once ("functions.php"); / ** * Aby określić, czy użytkownik jest zalogowany, musimy * sprawdzić, czy w bazie danych znajdują się wpisy dotyczące jego loginu * i hasła. W tym celu wykorzystamy funkcję niestandardową * do sprawdzenia poprawności danych zalogowanego użytkownika. * Jeśli ta funkcja zwraca wartość false, oznacza to brak autoryzacji. * W przypadku braku autoryzacji po prostu przekierowujemy * użytkownika na stronę autoryzacji. * / // Jeśli sesja zawiera zarówno dane logowania, jak i hasła, // sprawdź je, // jeśli (isset ($ _ SESSION ["login"]) && $ _SESSION ["login"] && isset ($ _ SESSION ["hasło" ] ) && $ _SESSION ["hasło"]) (// Jeśli walidacja istniejących danych nie powiedzie się if (! CheckAuth ($ _ SESSION ["login"], $ _SESSION ["hasło"])) (// Przekieruj użytkownika do nagłówek strony autoryzacji ("location: login.php"); // zatrzymanie wykonania skryptu exit;)) // jeśli nie ma danych o loginie lub haśle użytkownika, // uważamy, że nie ma autoryzacji, przekieruj użytkownik // do strony autoryzacji else ( nagłówek ("location: login.php"); // Przerwij wyjście ze skryptu;)

Teraz utwórzmy kod dla naszej bezpiecznej strony. To będzie całkiem proste.

Autoryzacja i rejestracja użytkownika

Udana autoryzacja.

Masz dostęp do bezpiecznej strony. Możesz wylogować się z systemu.

Jak widać, w chronionym dokumencie umieszczamy tylko jeden plik - checkAuth.php. Wszystkie inne pliki są zawarte w innych skryptach. Dlatego nasz kod nie wygląda na kłopotliwe. Zorganizowaliśmy rejestrację i autoryzację użytkowników. Teraz musisz zezwolić użytkownikom na wylogowanie. W tym celu stworzymy skrypt w pliku logout.php.

/ ** * Skrypt wylogowania użytkownika. Ponieważ użytkownicy są * autoryzowani poprzez sesje, ich login i hasło są przechowywane * w tablicy $_SESSION supergloban. Aby wylogować się z systemu wystarczy zniszczyć wartości * tablicy $ _SESSION ["login"] i $ _SESSION ["hasło"], po czym * przekierowujemy użytkownika na stronę autoryzacji * / // Bądź pewny aby rozpocząć sesję session_start (); unset ($_SESSION ["login"]); unset ($_SESSION ["hasło"]); nagłówek ("lokalizacja: login.php");

Skrypt do rejestracji, autoryzacji i weryfikacji użytkowników jest gotowy. Możesz go używać w domu, uzupełniać, zmieniać według własnych potrzeb. Jeśli masz jakieś pytania, możesz je zadać w komentarzach. Wszystkie wymienione tutaj pliki możesz pobrać samodzielnie, spakowane do jednego archiwum.

PS Zdaję sobie sprawę, że lepiej pisać kod obiektowy, wiem, że nie warto przekazywać i przechowywać hasła w postaci zwykłego tekstu, że informacje wprowadzone do bazy należy wcześniej sprawdzić. Ja wiem. Nie będę o tym tutaj mówić.

Cześć! Teraz postaramy się zaimplementować najprostszą rejestrację w serwisie za pomocą PHP + MySQL. Aby to zrobić, na komputerze musi być zainstalowany Apache. Zasadę naszego skryptu przedstawiamy poniżej.

1. Zacznijmy od stworzenia tabliczki użytkowników w bazie danych... Będzie zawierać dane użytkownika (login i hasło). Przejdźmy do phpmyadmina (jeśli tworzysz bazę na swoim komputerze) http://localhost/phpmyadmin/). Utwórz stół użytkownicy, będzie miał 3 pola.

Tworzę go w bazie mysql, możesz utworzyć w innej bazie. Następnie ustaw wartości, jak na obrazku:

2. Wymagane jest połączenie z tą tabelą. Stwórzmy plik bd.php... Jego zawartość:

$db = mysql_connect ("Twój serwer MySQL", "zaloguj się do tego serwera", "hasło do tego serwera");
mysql_select_db ("nazwa bazy danych, z którą się łączymy", $db);
?>

W moim przypadku wygląda to tak:

$db = mysql_connect ("localhost", "user", "1234");
mysql_select_db („mysql”, $db);
?>

Ratujemy bd.php.
W porządku! W bazie danych mamy tabelę, połączenie z nią. Teraz możesz zacząć tworzyć stronę, na której użytkownicy będą zostawiać swoje dane.

3. Utwórz plik reg.php z zawartością (wszystkie komentarze w środku):



rejestracja


rejestracja
















4. Utwórz plik, który wprowadzi dane do bazy i zapisze użytkownika. save_user.php(komentarze w środku):



{
}
// jeśli jest wpisany login i hasło, to przetwarzamy je tak, aby nie działały tagi i skrypty, nigdy nie wiadomo, co ludzie mogą wpisać


// usuń dodatkowe spacje
$ login = przycinanie ($ login);
$ hasło = przyciąć ($ hasło);
// połącz się z bazą danych
// sprawdź, czy istnieje użytkownik o tym samym loginie
$ wynik = mysql_query ("SELECT id FROM users WHERE login =" $ login "", $ db);
if (! pusty ($ myrow ["id"])) (
exit („Przepraszamy, wprowadzona nazwa użytkownika jest już zarejestrowana. Proszę podać inną nazwę użytkownika.”);
}
// jeśli nie, to zapisz dane
$ wynik2 = mysql_query („WSTAW UŻYTKOWNIKÓW (login, hasło) WARTOŚCI („$ login ”, „$ hasło”))”);
// Sprawdź, czy są jakieś błędy
if ($ wynik2 == "PRAWDA")
{
echo "Zarejestrowałeś się pomyślnie! Możesz teraz wejść na stronę. Strona główna";
}
w przeciwnym razie (
echo "Błąd! Nie jesteś zarejestrowany.";
}
?>

5. Teraz nasi użytkownicy mogą się zarejestrować! Następnie musisz zrobić „drzwi”, aby wejść na stronę dla już zarejestrowanych użytkowników. index.php(komentarze w środku):

// cała procedura działa na sesjach. To w nim przechowywane są dane użytkownika podczas jego pobytu w serwisie. Bardzo ważne jest, aby uruchomić je na samym początku strony !!!
start_sesji ();
?>


Strona główna


Strona główna











Zarejestruj się teraz



// Sprawdź, czy zmienne login i identyfikator użytkownika są puste
if (pusty ($ _ SESSION ["login"]) lub pusty ($ _ SESSION ["id"]))
{
// Jeśli jest pusty, nie wyświetlamy linku
echo "Jesteś zalogowany jako gość
Ten link jest dostępny tylko dla zarejestrowanych użytkowników ”;
}
w przeciwnym razie
{

W pliku index.php wyświetlimy link, który będzie otwarty tylko dla zarejestrowanych użytkowników. O to właśnie chodzi w skrypcie - ograniczenie dostępu do jakichkolwiek danych.

6. Istnieje plik z weryfikacją wprowadzonej nazwy użytkownika i hasła. testreg.php (komentarze w środku):

session_start ();// cała procedura działa na sesjach. To w nim przechowywane są dane użytkownika podczas jego pobytu w serwisie. Bardzo ważne jest, aby uruchomić je na samym początku strony !!!
if (isset ($ _ POST ["login"])) ($ login = $ _POST ["login"]; if ($ login == "") (unset ($ login);)) // wprowadź wprowadzony login przez użytkownika do zmiennej $ login, jeśli jest pusta, to niszczymy zmienną
if (isset ($ _ POST ["hasło"])) ($ hasło = $ _ POST ["hasło"]; if ($ hasło == "") (unset ($ hasło);))
// wstaw hasło wprowadzone przez użytkownika do zmiennej $ password, jeśli jest puste, zniszcz zmienną
if (pusty ($login) lub pusty ($hasło)) // jeśli użytkownik nie podał loginu lub hasła to wystawiamy błąd i zatrzymujemy skrypt
{
exit („Nie wpisałeś wszystkich informacji, wróć i wypełnij wszystkie pola!”);
}
// jeśli jest wpisany login i hasło, to przetwarzamy je tak, aby nie działały tagi i skrypty, nigdy nie wiadomo, co ludzie mogą wpisać
$ login = stripslashes ($ login);
$ login = htmlspecialchars ($ login);
$ hasło = paski ukośne (hasło $);
$ hasło = htmlspecialchars ($ hasło);
// usuń dodatkowe spacje
$ login = przycinanie ($ login);
$ hasło = przyciąć ($ hasło);
// połącz się z bazą danych
include ("bd.php"); // plik bd.php musi znajdować się w tym samym folderze co wszyscy inni, jeśli nie, po prostu zmień ścieżkę

$ wynik = mysql_query ("SELECT * FROM users WHERE login =" $ login "", $ db); // pobranie z bazy danych wszystkich danych o użytkowniku z podanym loginem
$ myrow = mysql_fetch_array ($ wynik);
if (puste ($ myrow ["haslo"]))
{
// jeśli użytkownik z podanym loginem nie istnieje
}
w przeciwnym razie (
// jeśli istnieje, sprawdź hasła
if ($ myrow ["hasło"] == $ hasło) (
// jeśli hasła są zgodne, rozpoczynamy sesję dla użytkownika! Możesz mu pogratulować, wszedł!
$ _SESSION ["zaloguj"] = $ myrow ["zaloguj"];
$ _SESSION ["id"] = $ myrow ["id"]; // te dane są bardzo często używane, więc zalogowany użytkownik "nosi ze sobą"
echo "Pomyślnie wszedłeś na stronę! Strona główna";
}
w przeciwnym razie (
// jeśli hasła się nie zgadzają

Wyjdź („Przepraszamy, wprowadzony login lub hasło jest nieprawidłowe.”);
}
}
?>

Więc to wszystko! Lekcja może być nudna, ale bardzo przydatna. Tutaj pokazana jest tylko idea rejestracji, potem można ją ulepszyć: dodać ochronę, projekt, pola danych, wgrać awatary, wylogować się z konta (w tym celu wystarczy zniszczyć zmienne z sesji funkcją nieoprawny) itp. Powodzenia!

Sprawdziłem wszystko, działa poprawnie!

Panie i Panowie,

A może powinienem powiedzieć „Gentle Ladies” i „Hard Men” (twardzi faceci)!

Oto mój najnowszy (nowy kod) reg.php. Zmodyfikowałem go przez:

  • Usuwanie nieaktualnych tagów strip, mysqli_escape_string.
  • Powiązane parametry wejściowe w formularzu rejestru użytkownika.
  • Dodano kod htmlspecialcharacters na wyjściu, aby zapobiec wstrzykiwaniu sql.

Zobacz, jak zagracony był mój stary kod, zanim pomogło mi tu wielu programistów i inne źródła (dzięki wszystkim!).

Ok, mój nowy kod nie zawiera kodu potwierdzającego e-mail i wielu innych, ale wkrótce je dodam. Wyciągnąłem je tutaj, aby nowy kod był prosty, abyś mógł łatwo zrozumieć kod. Zachowałem tylko podstawy na pierwszym wrażeniu. Doda pozostałe potrzeby do drugiego wrażenia.
Zachęcamy do zgłaszania wszelkich sugestii i krytykowania kodowania (ale postaraj się pokazać przykład poprawy w obszarze, który krytykujesz). Ok?

Stary kod:

connect_error) (die ($ conn-> connect_error);) // Szczegóły strony. $ site_domain = "site-domain.com"; $ nazwa_witryny = "nazwa-witryny"; $ site_admin_email = "admin@site-domain.com"; // Wykonaj następującą akcję po kliknięciu przycisku Prześlij podczas rejestracji użytkownika. if (isset ($ _ POST ["submit"])) (// Sprawdź, czy użytkownik wypełnił pola "Nazwa użytkownika", "Hasło" i "E-mail". Jeśli nie, powiadom o ich wypełnieniu. if ( pusty ($ _ POST ["member_registration_username"]) &&! pusty ($ _ POST ["member_registration_password"]) &&! pusty ($ _ POST ["member_registration_email"])) ($ member_registration_username = trim (strip_tags (strtolower (mysscape_real_) $ _POST ["member_registration_username"])))); $ member_registration_password = trim (strip_tags (md5 (mysqli_real_escape_string ($ conn, $ _ POST ["member_registration_password"])))); // Sprawdź dopasowanie nazwy użytkownika w tabeli użytkowników. $ Sql = "SELECT * FROM users WHERE Usernames =" ". $ Member_registration_username." ""; $ Result = mysqli_query ($ conn, $ sql); // Jeśli w kolumnie "Usernames" jest pasująca nazwa użytkownika, wykonaj następujące czynności .. if (mysqli_num_rows ($ wynik)! = 0) (// Podaj alert "nazwa użytkownika" już zajęty. $ _SESSION ["message"] = "Ta nazwa użytkownika $ member_registration_username jest już zarejestrowana!"; exit ();) / / Sprawdź r Dopasowanie adresu e-mail w tabeli użytkowników. $ sql = "SELECT * FROM users WHERE Emails =" ". $ member_registration_email." ""; $ wynik = mysqli_query ($ conn, $ sql); // Jeśli w kolumnie „Nazwy użytkowników” istnieje pasująca nazwa użytkownika, wykonaj następujące czynności ... if (mysqli_num_rows (wynik $)> 0) (// Podaj alert „e-mail” już zajęty. $ _SESSION ["wiadomość"] = "Ten e-mail $ member_registration_email jest już zarejestrowany!"; Exit ();) // Zrzuć nową "Nazwa użytkownika", "E-mail" i "Hasło" do tabeli "użytkownicy". $ sql = "WSTAW użytkowników (nazwy użytkowników, hasła, e-maile) WARTOŚCI (" ". $ member_registration_username." "," ". $ member_registration_password." "," ". $ member_registration_email." ")"; if ($ sql) (// Pomyśl o zrzuceniu nowych danych użytkownika do bazy danych. $ _SESSION ["wiadomość"] = "Wstawienie danych do tabeli powodzenie!";) else (// Poinformuj o zrzuceniu danych nowego użytkownika do bazy danych błąd $ _SESSION ["message"] = "Niepowodzenie wstawiania danych do tabeli!";)) else (// Alarm, aby wypełnić wszystkie pola. $ _SESSION ["message"] = "Musisz wypełnić wszystkie dane wejściowe pola! ”;))?> <?php $site_name ?>Strona rejestracji

Formularz rejestracyjny

Nowy kod:

przygotowanie ("INSERT INTO tbl_users (nazwa, hasło) WARTOŚCI (?,?)")) (// Powiąż zmienne z parametrem jako ciągi znaków. $ stmt-> bind_param ("ss", $ nazwa, $ hasło); / / Wykonaj instrukcję $ Stmt-> execute (); // Zamknij przygotowaną instrukcję $ Stmt-> close ();)) else (// Informuj o wypełnieniu wszystkich pól. Echo "Musisz wypełnić wszystkie pola wejściowe! ";))?> <?php $site_name ?>Strona rejestracji

Formularz rejestracyjny

Koledzy programiści, patrząc na mój drugi kod, czy myślicie:

  • to jest lepsze;
  • bez bałaganu;
  • bardziej zrozumiałe;
  • bez wtrysku sql.

A w moim drugim kodzie, czy możesz mi pomóc przekonwertować polecenie INSERT sql (wiersz 45-55) na styl mysqli z pdo?
Otrzymałem ten kod pdo z:
wikihow.com

Jak zapobiegać wstrzykiwaniu SQL w PHP

Wstrzyknięcie SQL jest obecnie jedną z najczęstszych luk w aplikacjach internetowych. Z tego artykułu dowiesz się, jak w 100% zapobiec wstrzykiwaniu SQL na swojej stronie internetowej za pomocą przygotowanych instrukcji w PHP. SQL Injection to rodzaj ...

Ponieważ większość mojego kodu, w moim wielostronicowym skrypcie, jest w stylu mysqli lub proceduralnym, będzie wyglądać dziwnie, jeśli 10 wierszy będzie w stylu pdo lub oop.
Tak, wiem, że wiem, powinienem to zrobić w stylu pdo i oop, ale „nadal jestem początkującym i większość samouczków na temat podstawowego php jest w stylu mysqli i proceduralnym, więc nie mogę jeszcze przełączyć się na pdo i oop. Pozwól mi najpierw naucz się chodzić, a potem podskoczę jak kangur. „Nadal jestem małym dzieckiem. Muszę robić wszystko krok po kroku, albo się zdezorientuję i zniechęcę się do php.

Pytanie: Na moim pierwszym (starym kodzie) zobaczysz, że zamiast tego nie używam „echa”, ale „Wiadomość sesji”, ponieważ 2 samouczki na YouTube pokazały, że robię to w ten sposób, nie podając żadnego wyjaśnienia, dlaczego. Dlatego proszę:

  1. Jaka jest różnica i zalety (plusy), a także wady między echem a komunikatem sesji?
  2. Kiedy powinienem użyć którego z nich?


© 2021 skypenguin.ru - Wskazówki dotyczące opieki nad zwierzętami