Asynchroniczne interfejsy Walidacja danych WWW mgr inż. Rafał Grycuk mgr inż. Patryk Najgebauer Strona służbowa: http://iisi.pcz.pl/~rgrycuk/ Kontakt: rafal.grycuk@iisi.pcz.pl Konsultacje: Środa, godz. 12-14
Agenda 1. Co to jest Walidacja danych?, 2. Wyrażenia regularne, 3. Wyrażenia regularne w JavaScript. 4. Walidacja danych po stronie serwera.
Walidacja danych Walidacja danych polega na sprawdzaniu poprawności danych wejściowych. Walidujemy dane w celu wyeliminowania: błędów użytkownika np. źle podany pesel, kod pocztowy; danych niezgodnych z regulaminem np. wulgaryzmy, odnośniki do konkurencyjnych stron; treści szkodliwych dla strony np. skrypty JavaScript, zapytania SQL;
Walidacja danych Wszystkie informacje trafiające od użytkownika na serwer są przesyłane w formie tekstowej, więc należy sprawdzić co dokładnie przyszło od klienta. Walidując parametry: typów prostych (int, float) możemy je prasować dzięki gotowym metodom. typów niestandardowych (adres,email) musimy skorzystać z wyrażeń regularnych. Istnieją również dane jak numery NIP, PESEL posiadające wartości kontrolne. Natomiast w tekstach występują też potrzeby usuwania słów niepożądanych metodą słownikową.
Wyrażenia regularne Są to wzorce opisujące łańcuchy znaków. Możemy za ich pomocą wyszukać, pociąć lub porównać dane wejściowe pasujące do naszego wzorca. Przykładowo poniższe wyrażenie regularne będzie pasować do kodów pocztowych np. 42-200 ^([0-9]{2}-[0-9]{3})$
^([0-9]{2}-[0-9]{3})$ - łańcuch na wejściu musi być zgodny od początku do końca z wyrażeniem regularnym. ^([0-9]{2}-[0-9]{3})$ - odnosi się do dwóch początkowych cyfr kodu pocztowego. ^([0-9]{2}-[0-9]{3})$ - określa zbiór znaków od 0 do 9. ^([0-9]{2}-[0-9]{3})$ - muszą wystąpić 2 znaki zgodne ze zbiorem. ^([0-9]{2}-[0-9]{3})$ - znak myślnika w kodzie pocztowym. ^([0-9]{2}-[0-9]{3})$ - trzy ostatnie cyfr kodu pocztowego.
Grupowanie wyrażeń alternatywa. ( ) grupowanie wyrażań regularnych (?: ) grupowanie bez zapamiętywania wyniku \n - referencja do zapamiętanej grupy (back references) liczonej od początku. Łańcuch pod referencją musi być zgodny z łańcuchem z grupy na którą jest wskazanie.
Grupowanie wyrażeń przykłady wyszukiwania (12 21)abc wyrażenie zgodne z łańcuchami 12abc lub 21abc (12 21)abc\1 wyrażenie zgodne z łańcuchami 12abc12 lub 21abc21 (4 (?:5 6))(12 21)abc\2 bez grupowania (?: referencja \2 mogła by odwoływać się do dwóch różnych grup.
Asercja przetwarzanie warunkowe Asercja pozwala badać otoczenie szukanego łańcucha znaków przy jednoczesnym nie włączaniu ich do rezultatu. (?= ) Asercja zstępna pozytywna (?! ) Asercja zstępna negatywna (?<= ) Asercja wstępna pozytywna (?<! ) Asercja wstępna negatywna
Asercja - przykłady (?<=12 21)abc wyrażenie zgodne z łańcuchami abc poprzedzonymi 12 lub 21 (?<=12 21)abc(?=12 21) wyrażenie zgodne z łańcuchami abc otoczonymi 12 lub 21 (?<=(12 21))abc(?=12 21)(?!\1) wyrażenie zgodne z łańcuchami abc otoczonymi 12 lub 21 różnymi od siebie
Klasy znaków Klasy pozwalają określić zbiory znaków jakie mogą wystąpić w szukanym łańcuchu. [abcd] klasa zbioru znaków zgodnych. [^abcd] klasa zbioru znaków niezgodnych. [a-z] - zakres znaków zgodnych z wzorcem.
Klasy znaków - przykłady (?<=[ +])abc(?=[,0-9]) wyrażenie pasujące do łańcucha abc otoczonego z lewej spacją lub + oraz z prawej spacją,, i znakami od 0 do 9. (?<=[^-0-9]) [0-9] [0-9]-[0-9] [0-9] [0-9] (?![-0-9]) wyrażenie pasujące do kodów pocztowych nie otoczonych znakami - oraz znakami od 0 do 9.
Liczeności {n} dokładnie n powtórzeń {n,} co najmniej n powtórzeń {n,m} od n do m powtórzeń * - zero lub więcej powtórzeń ( {0,} ). + - jedno lub więcej powtórzeń ( {1,} ).? - zero lub jedno powtórzeń ( {0,1} ). {n,}? co najmniej n powtórzeń ale jak najmniej {n,m}? od n do m powtórzeń, ale jak najmniej *? - zero lub więcej powtórzeń ( {0,} ), ale jak najmniej +? - jedne lub więcej powtórzeń ( {1,} ), ale jak najmniej.?? - zero lub jedno powtórzeń ( {0,1} ), ale jak najmniej.
Liczeności - przykłady (00){0,}abc(df)+ - wyrażenie wyszuka łańcuchy abc wraz z parzystą ilością 0 po lewej i co najmniej raz powtórzonymi znakami df po prawej Abcdf00abcabcdfdfabc00000abcdfabcdf (00){0,}?abc(df)+? - wyrażenie wyszuka łańcuchy abc wraz z parzystą ilością 0 po lewej i co najmniej raz powtórzonymi znakami df po prawej abcdf00abcabcdfdfabc00000abcdfabcdf
Liczeności - przykłady (?<=[^-0-9]) [0-9]{2}- [0-9]{3} (?![-0-9]) wyrażenie pasujące do kodów pocztowych nie otoczonych znakami - oraz znakami od 0 do 9.
Standardowe znaki specjalne \0 pusty znak, w programowaniu znak końca string-a (\u0000) \t znak tabulacji (\u0009) \n nowa linia (\u000a) \v znak tabulacji pionowej (\u000b) \xnn znak ASCI w kodowaniu hexadecymalnym nn. \onn znak ASCI w kodowaniu ósemkowym nn. \unnnn znak Unikodu w kodowaniu hexadecymalnym nn. \cx znak sterujący X
Znaki specjalne w wyrażeniach regularnych \ - Znak specjalny zostanie zmieniony na znak tekstu i na odwrót.. - dowolny znak z wyjątkiem '\n' \w dowolna litera, cyfra lub znak podkreślenia ([a-za-z0-9_]) \W dowolny znak niebędący literą, cyfrą lub znakiem podkreśleniem ([^a-za-z0-9_]) \s znak spacji. \S każdy znak z wyjątkiem spacji. \d znaki cyfr ([0-9]) \D każdy znak z wyjątkiem cyfr ([^0-9])
Znaki kotwiczne Znaki kotwiczne pozwalają określić obszar łańcucha znaków, dla którego ma być sprawdzane wyrażenie. Działają w podobny sposób do asercji. ^ - początek łańcucha znaków. $ - koniec łańcucha znaków. \b granica wyrazu. \B - pozycja niebędąca granicą wyrazu
Znaki kotwiczne - przykłady \b[a-z]+\b wyrażenie wyszuka łańcuchów składających się ze znaków od a do z przy czym wyszukany łańcuch musi być osobnym wyrazem. \b[0-9]+ wyrażenie wyszuka łańcuchy cyfr, które są również początkami wyrazów.
Znaki kotwiczne - przykłady ^ [a-z]+ wyrażenie wyszuka ciąg składających się ze znaków od a do z przy czym wyszukany ciąg musi być na początku łańcucha wejściowego. ^[0-9]+$ wyrażenie wyszuka, a raczej zwaliduje łańcuch, który będzie składał się z samych cyfr.
Klasy a polskie znaki Niemożliwe jest określenie klasy polskich znaków przez zakres znaków ([ą-źą-ź]) musimy je wypisać ([ąćęłńóśźżąćęłńóśźż]) spowodowane to jest tym, że znaki polskie są wspólne z innymi językami i ich kody unikodu są rozrzucone np. ą(\u0105), ć(\u0107), ó(\u00f3), ż(\u017c). Jak widać nie da się ich potraktować jako zakres znaków.
Wyrażenia regularne - przykłady ^abc wyrażenie zgodne z łańcuchami rozpoczynającymi się od abc. abcabc abc abc$ - wyrażenie wyszuka ciąg abc, który kończy łańcuch. abcabc abc
Wyrażenia regularne - przykłady ^abc$ wyrażenie pasujące do łańcuchów abc. abc zgodne abab abc niezgodne ^(abc cba)k2$ - wyrażenie pasujące do łańcuchów rozpoczętych abc lub cba i zakończonych k2. cbak2 zgodne cbak2 w niezgodne
Wyrażenia regularne - przykłady ^(abc cba).+k2$ - wyrażenie pasujące do łańcuchów rozpoczętych abc lub cba i zakończonych k2 poprzedzonego dowolnymi znakami. cba..k2 zgodne cbak2k2 zgodne cbak2 niezgodne ^(abc cba)(.+)k2\2$ - \2 oznacza, że po prawej stronie k2 musi znaleźć się ciąg zgodny z (.+) po jego lewej stronie. cba...k2... zgodne cbak2k2k2 zgodne cbak2k2 niezgodne
Wyrażenia regularne - przykłady [0-9]{2}-[0-9]{3} wyrażenie wyszuka kody pocztowe. 1242-20042-6005 45- ^([0-9]{2}-[0-9]{3} ) $ - wyrażenie pasujące do kodu pocztowego 20-120 zgodny 1220-222 niezgodny
Wyrażenia regularne - przykłady [^0-9]* - wzór pasujący do wszystkich znaków z wyjątkiem cyfr. 12d42-200_/l?_42-600xsds5sxs45- \d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3} wzór pasuje do adresów IP. ws192.168.1.1sdsw dws192.168,1.1sdsw d
Wyrażenia regularne - przykłady [a-z0-9_.-]+@[a-z0-9_.-]+\.[a-z]{2,4} - wzór pasujący do adresu email. adres_adres.tf@dmm.pl fg@hj.tc (?=([^,]*[0-9]){3,})(?=([^,]*[A-B]){2,}) [^,]{5,} wyrażenie wyszuka łańcuchy minimum 5 znaków rozdzielonych znakiem,, zawierających 3 cyfry i 2 duże litery. 123AB,1A23B,aaaa123,a2b#AB+12,12
Wyrażenia regularne - przykłady (?=^.{5,}$)(?=(.*[0-9]){3,})(?=(.*[A-B]){2,})^.*$ - wzór walidujący hasła zawierające min. 5 znaków w tym 2 duże litery i 3 cyfry. 123AB zgodne 1A23Bdsdf zgodne aaaa123 niezgodne
Uwaga Walidacje ze względów bezpieczeństwa należy przeprowadzać po stronie serwera. Możliwość podesłania spreparowanego formularza. Walidacja po stronie klienta jest sprawą kosmetyczną, usprawniającą użytkownikowi korzystanie ze strony.
JavaScript Wyrażenia regularne Metody klasy string obsługujące wyrażenia regularne: match(wzór) metoda szuka pasujących do wzorca treści, następnie zwraca ich zbiór lub NULL jeśli nic nie znalazła. replace(wzór, zastępnik) metoda zastępuje treść pasującą do wzorca zastępnikiem. search(wzór) wyszukuje treści pasującej do wzorca i zwraca jej pozycje w stringu lub -1 jeśli nic nie znajdzie. split(wzór, limit) dzieli string-a na podstawie wzorca, dodatkowo można nadać limit rozdzielonych elementów.
JavaScript Wyrażenia regularne Wyrażenia regularne definiujemy wprowadzając ich treść w znakach / var re = /^([%]?[0-9A-Za-z])$/; str.match(re); str.match(/^([%]?[0-9a-za-z])$/);
MVC Walidacja modelu (model) namespace TestAplication.Models { [MetadataType(typeof(osobaValidate))] public partial class osoba { } [Bind(Exclude = "id")] public class osobavalidate { [Required(ErrorMessage = "Podaj nazwisko")] [StringLength(20, ErrorMessage="Nazwisko max 20 znaków")] [RegularExpression("^([a-zA-ZąćęłńóśźżĄĆĘŁŃÓŚŹŻ]+)$", ErrorMessage="Nazwisko tylko litery")] public string nazwisko { get; set; } [Required(ErrorMessage = "Podaj imie")] [StringLength(20, ErrorMessage = "Imie max 20 znaków")] [RegularExpression("^([a-zA-ZąćęłńóśźżĄĆĘŁŃÓŚŹŻ]+)$", ErrorMessage="Imie tylko litery")] public string imie { get; set; } [Required(ErrorMessage = "Podaj wiek")] [Range(1,130, ErrorMessage = "Wiek od 1 do 130")] [RegularExpression("^([0-9]+)$", ErrorMessage="Wiek tylko liczby")] public string wiek { get; set; }
MVC Walidacja modelu (Controller) [HttpPost] public ActionResult Dodaj(osoba os) { if (ModelState.IsValid) // informacja o zgodności modelu { repo.dodaj(os); if (Request.IsAjaxRequest()) return PartialView("OsobaTab", repo.pobierzliste()); return RedirectToAction("Index"); } if (Request.IsAjaxRequest()) { ViewData["errors"] = ModelState.Values.SelectMany(v => v.errors); return PartialView("OsobaTab", repo.pobierzliste()); } return View(os); }
* * * MVC Walidacja modelu (View) <% Html.EnableClientValidation(); %> // treść wprowadzanych danych będzie na bieżąco sprawdzana u klienta <% using (Html.BeginForm()) {%> <%: Html.ValidationSummary(true) %> <fieldset> <legend>fields</legend> <div class="editor-label"> <%: Html.LabelFor(model => model.nazwisko) %> </div> <div class="editor-field"> <%: Html.TextBoxFor(model => model.nazwisko) %> <%: Html.ValidationMessageFor(model => model.nazwisko) %> </div>
C# Wyrażenia regularne W C# z wyrażeń regularnych można korzystać za pomocą klasy Regex. Posiada ona między innym metody: bool IsMatch(String) Match Match(String) string Replace(String, String) string[] Split(String)
C# Wyrażenia regularne Regex patern = new Regex("^([0-9]*)$"); if (!patern.ismatch("34,8")){ // jakaś akcja }
Sumy kontrolne nr. PESEL Nr PESEL składa się z 11 cyfr z czego ostatnia jest kontrolna. W celu walidacji nr PESEL należy: Uzyskać sumę 10 pierwszych cyfr mnożonych przez ich wagi sum = 1*P1+3*P2+7*P3+9*P4+1*P5+3*P6+7*P7+9*P8+1*P9+3*P10 Uzyskać wartość modulo 10 z sumy. mod = sum%10 Uzyskać wartość kontrolną i sprawdzić zgodność z 11 cyfrą nr PESEL wynik = (10-mod)%10 == P11
Źródła http://myregexp.com/ - strona z apletem do pisania i testowania wyrażeń regularnych.