Posts tagged Router
3 część kursu Router
0Zapraszam na trzecią część kursu o wzorcu Router. W tej części pokazałem jak zrobić algorytm odnajdywania właściwego kontrolera oraz jak zapisać nazwę kontrolera, metody i argumentów. Zapraszam serdecznie do lektury:
Uwagi i komentarze mile widziane
Wzorce projektowe: Router – cz. 2
0Informacje wstępne
W tej części chciałbym skupić się na prostej metodzie filtrowania niebezpiecznych znaków na wejściu.
Implementacja
Ostatni raz klasa miała następującą postać
class Router {
public static $current_uri = '';
public static function get_uri()
{
if (!empty($_SERVER['PATH_INFO']))
{
self::$current_uri = $_SERVER['PATH_INFO'];
}
}
}
Dodajmy więc następne elementy. Zaznaczone na zielono.
class Router {
public static $current_uri = '';
public static function get_uri()
{
if (!empty($_SERVER['PATH_INFO']))
{
self::$current_uri = $_SERVER['PATH_INFO'];
}
self::$current_uri = trim(self::$current_uri, '/ ');
if (self::$current_uri !== '')
{
self::$current_uri = preg_replace('#//+#', '/', self::$current_uri);
self::$current_uri = str_replace(' ', '_', self::$current_uri);
self::$current_uri = preg_replace("/[^a-z0-9\\-\\_\\/\\,]/i", '', self::$current_uri);
}
}
}
- W linii 12 dodaliśmy funkcję “trim”, która obcina po lewej i po prawej stronie tekstu znaki, które podamy w parametrze. Domyślnie usuwa białe znaki (spacja, enter, tabulator). My chcemy pozbyć się niepotrzebnych slashy i białych znaków.
- Następnie sprawdzamy czy cokolwiek po tej operacji zostało w zmiennej $current_uri (linia 14). Jeśli jest różne od pustego ciągu do wykonujemy dodatkowe zabezpieczenie
- W linii 14 wyrażenie regularne usuwa wielokrotne slashe, np: jeśli na wejściu będzie “konto///klient//zobacz” to zamieni to na “konto/klient/zobacz”
- W linii 18 spacje zamieniane są na podkreślniki. To jeden z najprostszych sposobów oddzielania wyrazów w adresach stron. Ewentualnie można jeszcze zastosować myślnik
- Wreszcie w linii 20 wyrażenie regularne usuwa z wejścia wszystko co nie jest znakiem dopuszczanym (nie znajduje się na liście). W tym przypadku wyrażenie regularne pozostawi tylko znaki alfanumeryczne, przecinek i slash. W zależności od potrzeb można ta listę wydłużyć/zmienić
Ostateczna postać klasy:
class Router {
public static $current_uri = '';
public static function get_uri()
{
if (!empty($_SERVER['PATH_INFO']))
{
self::$current_uri = $_SERVER['PATH_INFO'];
}
self::$current_uri = trim(self::$current_uri, '/ ');
if (self::$current_uri !== '')
{
self::$current_uri = preg_replace('#//+#', '/', self::$current_uri);
self::$current_uri = str_replace(' ', '_', self::$current_uri);
self::$current_uri = preg_replace("/[^a-z0-9\\-\\_\\/\\,]/i", '', self::$current_uri);
}
}
}</pre>
Przykładowe wywołanie kodu:
Router::get_uri(); echo Router::$current_uri;
Kod wywołania nie zmienił się. Spróbuję jednak podać przykład “brzydkiego” wejścia.
http://moja.strona/stroąna[45],param1/zob&*acz
Efekt powinien być taki:
strona45,param1/zobacz
Jak widać wejście dobrze zabezpieczone – zezwala tylko na takie znaki jakie ma zdefiniowane
Podsumowanie
Starałem się krótko przedstawić proste zasady uniknięcia problemów i nieprzyjemności z dalszymi operacjami na wejściu. Można oczywiście mnożyć ilość przypadków, znaków i sytuacji które należy obsłużyć ale podane reguły sa na obecną chwilę całkowicie wystarczające.
Przedstawione zabezpieczenia nie mają na celu doprowadzić adresu z wejścia do czegoś konkretnego. Np jeśli nasza aplikacja posiada akcję “/klient/logowanie” a ktoś zamiast tego wpisze (np haker) /klient/logowanie<script>złośliwykod</script>” albo sql injection w stylu “/klient/’ or 1=1 ‘” itd to system niebezpieczne ciągu znaków odrzuci i zostawi tylko to co się nadaje i jest bezpieczne. W związku z tym dalej możemy szukać czy mimo wszystko coś sensownego z tego da się wyciągnąć. Tworząc linki w naszej aplikacji wiemy jakie one są: np na stronie głównej zrobimy “/klient/logowanie” ale to nie znaczy, że ktoś ręcznie w przeglądarce wpisze sobie coś innego (czego nie jesteśmy w stanie przewidzieć). Dzięki tym zabezpieczeniom system najwyżej takiej osobie, która próbuje manipulować linkami powie, że taka strona nie istnieje i nie wpłynie to na bezpieczeństwo samej aplikacji. Ustalmy, że to Router ma dostarczyć dane w sposób bezpieczny tak, aby reszta aplikacji nie musiała się już tym martwić
W następnym artykule przedstawię sposób rozbicia wejścia na użyteczne informacje
Nowy kurs – Router
0Przygotowałem dosyć krótki i prosty wstęp z przykładową implementacją wzorca projektowego Router. Krok po kroku będę prezentował kolejne etapy rozwoju i implementacji poszczególnych elementów tego obiektu.
Zapraszam serdecznie do zapoznania się z pierwszym artykułem na ten temat – Router
Zobacz także ogólnie – Wzorce projektowe
Wzorce projektowe
0Wzorce Projektowe, które powstały po to aby w miarę spójnie rozwiązywać problemy przy projektowaniu systemów.
O wzorcach projektowych powstało na pewno wiele mądrych i obszernych książek więc nie ma sensu abym ja się tutaj rozpisywał.
Przygotowałem kursy i implementacje popularnych i często używanych w programowaniu wzorców projektowych.
Wzorce projektowe: Router – cz. 1
0Informacje wstępne
Co to takiego ten Router i do czego on służy? Podobnie jak od strony technicznej jest to pewien “byt” zajmujący się odnajdywaniem/trasowaniem/przekazywaniem zadanych żądań.
W programowaniu Router to jeden z tzw Wzorców Projektowych, które powstały po to aby w miarę spójnie rozwiązywać problemy przy projektowaniu systemów.
O wzorcach projektowych powstało na pewno wiele mądrych i obszernych książek więc nie ma sensu abym ja się tutaj rozpisywał. Po co nam ten Router? Routerem nazwiemy obiekt, który będzie się zajmował pobieraniem adresu z przeglądarki i przetwarzaniem go na akcję zrozumiałą dla pozostałych elementów systemu. To on będzie decydował o tym, co ma się pojawić na wyjściu gdy pojawi się coś na wejściu.
Przykład:
Jeśli wpiszemy w przeglądarce:
http://moja.strona/witaj
Router odbierze na wejściu “witaj” i wg jemu znanego systemu przekaże dalej to żądanie – np “powie” systemowi, że należy wyświetlić stronę z powitaniem. Inny przykład:
http://moja.strona/
Router może mieć zaprogramowane domyślne akcje w przypadku braku konkretnych żądań. Przykładowo jeśli nie podano nic na wejściu to Router przekaże, że należy wyświetlić stronę główną.
Implementacji takiego systemu jest tak wiele jak i programistów jednakże pewne zasady ze względu na wzorce projektowe i wymagania techniczne są niezmienne i konieczne do poprawnego zrealizowania zadania.
Implementacja
W kolejnych krokach postaram się opracować prostą ale w pełni funkcjonalną implementację takiej klasy. Zacznijmy od opracowania podstawowych metod tej klasy
class Router {
public static $current_uri = '';
public static function get_uri()
{
if (!empty($_SERVER['PATH_INFO']))
{
self::$current_uri = $_SERVER['PATH_INFO'];
}
}
}
Pole $current_uri będzie przechowywać pobrany adres na wejściu – zostanie on użyty później.
Metoda get_uri() powinna zostać uruchomiona na początku działania systemu. Jej zadaniem jest pobranie z pola tablicy superglobalnej $_SERVER wartości PATH_INFO. Pod tym polem kryje się wszystko to co zostało zapisane za plikiem, który uruchama skrypt – np index.php. Zatem jeśli w przeglądarce wpiszemy:
http://moja.strona/index.php/konto/rejestracja
To PATH_INFO będzie zawierało wartość
/konto/rejestracja
Zmienna $current_uri została domyślnie zainicjowana na wartość pustą. Jeśli jednak PATH_INFO było niepuste to przypiszmy tą wartość do $current_uri.
Przykładowe wywołanie kodu:
Router::get_uri(); echo Router::$current_uri;
Tyle ma do roboty Router jeśli chodzi o odbieranie danych.
Podsumowanie
To jest oczywiscie bardzo prosta implementacja jednakże w pełni skuteczna i wystarczająca do dalszej “obróbki”. W kolejnej części postaram się pokazać podstawowe sposoby zabezpieczenia wejścia i rozbijanie wejścia na konkretne akcje.
Następna część: Router cz. 2