Zabezpieczenie użytkowników hasłem

[info] Jeśli pracujesz na laboratorium, aby rozpocząć realizację kolejnego modułu, musisz wykonać poniższe operacje

  • sklonuj repozytorium ze swoim kodem (git clone ŚCIEŻKA_DO_REPOZYTORIUM),

  • zainstaluj potrzebne gemy (bundle install --path vendor/bundle),

  • dokonaj migracji bazy danych (rails db:migrate)

  • uruchom serwer (rails server)

Walidatory

Jeśli w tej chwili spróbujemy utworzyć użytkownika z pustym zarówno numerem indeksu, jak imieniem, operacja się uda, co nie jest przesadnie pożądanym rozwiązaniem. Szczęśliwie, w pliku modelu (czyli na przykład app/models/student.rb) możemy określić wymagania wobec pól opisujących obiekty zapisywane w naszej bazie. Realizujemy to przy użyciu tak zwanych walidatorów.

Uzupełnijmy model studenta o dwa walidatory:

  • Nazwa użytkownika (name) ma być zawsze obecna (presence: true), niepowtarzalna (uniqueness: true) i zawierać się w od trzech do pięćdziesięciu znaków (length: { in: 3..50 }):

validates :name, presence: true, uniqueness: true
, length: { in: 3..50 }
  • Numer indeksu (index) ma być również zawsze obecny i niepowtarzalny ale ma składać się z dokładnie sześciu znaków (length: { is: 6 }):

validates :index, presence: true, length: { is: 6 }, uniqueness: true

Kolejna próba utworzenia pustego użytkownika zakończy się listą błędów zgodną ze zdefiniowanymi przez nas walidacjami.

Więcej o walidatorach przeczytasz w dokumentacji Ruby on Rails (Active Record Validations).

Bezpieczne hasło

Jeśli użytkownicy (studenci) mają logować się w naszej aplikacji, ich konta powinny być zabezpieczone hasłem. Szczęśliwie, aby dodać hasło do modelu, możemy skorzystać z domyślnego rozwiązania, skracającego naszą pracę.

Na początek musimy dodać gem bcrypt do Gemfile (a w zasadzie odkomentować już obecny tam wpis).

Po każdej zmianie w Gemfile musimy zaktualizować paczki (bundle install --path vendor/bundle) i uruchomić ponownie serwer.

Kiedy projekt uzupełniony jest o bcrypt, możemy wskazać w modelu studenta informację o bezpiecznym haśle, uzupełniając go o dyrektywę has_secure_password:

Przejdźmy znów do webowego interfejsu aplikacji i spróbujmy utworzyć nowego użytkownika. Przeczytamy wtedy komunikat błędu informujący nas o tym, że w bazie danych brakuje pola password_digest. Jest to miejsce na tak zwany hash hasła, niezbędny do weryfikacji poprawności danych wprowadzonych przy logowaniu, który pozwala na to, aby hasło w czystej formie nie znalazło się w bazie.

Utwórzmy więc migrację, która doda odpowiednie pole.

  • rails generate migration AddPasswordDigestToStudents password_digest:string

Powyższe wywołanie generatora sprawi, że migracja sama wypełni się oczekiwanymi wpisami.

Możemy teraz zmigrować bazę danych (rails db:migrate) i spojrzeć na zaktualizowany diagram ERD (rails erd).

Jak widać, w modelu studenta pojawiło się nowe pole (password_digest). Możesz zauważyć również, że po zadeklarowaniu walidatorów niepowtarzalności dla numeru indeksu i nazwy użytkownika, ich wpisy na diagramie wzbogaciły się o flagę U.

Spróbujmy po raz kolejny utworzyć użytkownika. Tym razem aplikacja ma pretensje o brak hasła (dokładnie pola password, nie password_digest).

Niestety, w naszym formularzu nie znajduje się odpowiednie pole. Musimy więc go uzupełnić.

[info] Krótka informacja o formularzach

Korzystając z metody scaffoldingu, w wersji minimalnej, generowane są wszystkie niezbędne widoki. Możemy je odnaleźć w katalogu app/views/nazwa_naszego_modelu. Dzielą się one na zwyczajne widoki, powiązane z konkretną akcją kontrolera i tak zwane partiale, które możemy wyświetlać jako części innych widoków (możesz je rozpoznać po tym, że ich nazwy plików rozpoczynają się od podkreślnika). Formularz, który musi być obecny zarówno w widoku tworzącym nowy obiekt, jak i w widoku edycji, generowany jest właśnie jako partial _form.html.erb.

Przechodzimy do widoku app/views/students/_form.html.erb i w obrębie formularza dodajemy pole na hasło i jego potwierdzenie.

Podajmy poprawne dane w formularzu.

Okazuje się, że hasło, pomimo wprowadzenia, nadal jest interpretowane jako puste. Wynika to z prostego zabezpieczenia, które jest standardem w Ruby on Rails. Aby zrozumieć jego zasadę działania, odwiedźmy kontroler studenta. Mamy tu metodę student_params.

Dla bezpieczeństwa, aby nie przyjmować z sieci losowych zapytań, metoda student_params działa jako [biała lista](https://pl.wikipedia.org/wiki/Biała_lista_(informatyka)) pól, które można przesłać do kontrolera przez formularz. Musimy uzupełnić ją o hasło i jego potwierdzenie.

Teraz możemy już tworzyć nowych użytkowników z hasłem! Nie mamy jednak żadnych wymagań wobec jego złożoności. Możemy rozwiązać ten problem prymitywnym walidatorem, oczekujących od hasła co najmniej sześciu znaków.

Gratulacje! Zabezpieczyliśmy użytkowników hasłem.

[info] Aktualny kod

Na koniec każdego modułu znajduje się łącze do pełnej wersji kodu, który powinien być jego wynikiem.

Last updated