Technologie i narzędzia: język PHP 5, Java, JavaScript, Python, system Zend Framework, Django, biblioteka jQuery, Smarty, platforma Eclipse, MySQL, SVN, CVS, UML, Firefox.
WebProgramming - wszystko o serwisach internetowych
O serwisach internetowych.
[php|javascript] Kontrola praw.
Dzisiaj zaproponuje Wam ciekawy (moim zdaniem oczywiście) sposób na implementację kontroli praw po stronie widoku. Przyznam się szczerze, iż nie wykorzystałem go jeszcze w żadnym projekcie, ale jestem ciekawy co o nim sądzicie.
Załóżmy, że tworzymy panel administracyjny dla prostego CMS, w którym rozróżniamy następujące grupy użytkowników: administrator (posiada prawa zapisu, edycji, publikacji, usuwania), autor (posiada prawa zapisu i edycji). Realizację kontroli praw dostępu w większości przypadku odbywa się na dwóch płaszczyznach:
- akcja/kontroler - dla każdej wykonywanej akcji sprawdzamy, czy zalogowany użytkownik ma prawo ją wykonać
- widok - ukrywamy akcje do których aktualnie zalogowany użytkownik nie ma dostępu
Pierwsza jest konieczna ze względu na bezpieczeństwo, druga natomiast bardziej ze względu na usability (użytkownik widzi tylko akcje, do których ma prawo) i właśnie na niej skupię swoją uwagę w powyższym artykule.
Teraz pytanie jak w ładny i przejrzysty sposób ukryć to co użytkownik nie powinien widzieć? Od razu krzykniecie… to oczywiste powrzucać “ify”, o na przykład taki (widok jest skryptem php w systemie Zend Framework):
-
<?php if($this->hasAccessAdministrator): ?>
-
<a href="/page/delete/12/">usuń mnie</a>
-
<?php endif; ?>
-
<a href="/page/edit/12/">edytuj</a>
Przy bardziej zaawansowanych prawach skrypt widoku staje się jednak bardzo nieczytelny, za dużo warunków się w nim pojawia. Można by tego uniknąć tworząc dla każdego grupy użytkowników osobny skrypt widoku z tym, że to rozwiązanie kłóciłoby się z ideą DRY (ang. Don’t repeat yourself) i raczej nie jest praktykowane (całe szczęście).
Wpadłem jednak na dość nietypowe rozwiązanie, które może się okazać pomocne. Mianowicie domyślnie wszystkie akcje, które wymagają specjalnych praw są ukryte (np. za pomocą styli “display: none”). W zależności od prawa jakie użytkownik posiada ładujemy odpowiedni skrypt JavaScript. Skrypt ten odkrywa odpowiednie akcje - tylko te do których użytkownik ma rzeczywiście prawo. W tym przypadku skrypt widoku wyglądałby tak:
-
<a href="/page/delete/12/" class="hidden aDelete" >usuń mnie</a>
-
<a href="/page/edit/12/" class="hidden aEdit" >edytuj</a>
Natomiast skrypt JavaScript (jQuery) mniej więcej tak:
-
$(‘.aEdit’).show() // dla użytkownika zalogowanego jako autor lub administrator
-
$(‘.aDelete’).show() // dla użytkownika zalogowanego jako administrator
Dużym minusem tego rozwiązania wydaje się być umieszczenie w kodzie HTML linków do akcji, do których użytkownik nie ma prawa. Powiecie “przecież może sobie podejrzeć kod HTML i wykonać akcje bezpośrednio” i niby macie racje. Ale co z tego, że widzi linki? Ich uruchomienie i tak nie spowoduje wykonanie akcji, ze względu na kontrole praw w akcji/kontrolerze. Z drugiej strony nawet, gdy linki nie są widoczne to użytkownik może je łatwo odgadnąć na podstawie pozostałych linków - czyli jeżeli widzi link do edycji “/page/edit/12/ to nie trudno się domyślić, iż link do usuwania tejże pozycji będzie wyglądał mniej więcej tak “/page/delete/12/” lub “/page/remove/12″.
Prawdziwym minusem może się jednak okazać konieczność wspierania JavaScript przez przeglądarkę użytkownika, w związku z czym obecność JavaScriptu byłaby obowiązkowa. Spójrzmy jednak prawdzie w oczy - który panel administracyjny aktualnie opracowywany nie ma JavaScriptu?
Więc co jest minusem takiego rozwiązania? Oprócz oczywiście niekonwencjonalnego rozwiązania problemu? No właśnie nie widzę.. a Wy?
Update: podobny bajer można zrobić teoretycznie z plikami CSS zamiast skryptów JavaScript, z tym że w tym przypadku mamy mniejsze możliwości oraz zdaje się być jeszcze bardziej niekonwencjonalnym rozwiązaniem ![]()
1 Komentarz to “[php|javascript] Kontrola praw.”
Napisz komentarz
To generuje niepotrzebny narzut na łączach i na serwerze. Jeśli dla każdego usera byłby inny plik JS to jeszcze gorzej. Można się w tym pogubić a jak user ma dwie role to ściąga wiele niepotrzebnych danych. Ja mam zasadę “jeśli czegoś nie ma to nas to nie obchodzi”. Taka zasada sprawia że w programach praktycznie nie ma ifów. Oczywiście wymaga to znajomości kilku technologii. Najlepiej sprawdza się tu XSLT. Język ten wykonuje kod tak jak mu plik wejściowy każe. Tzn wykonuje przekształcenia wyłącznie dla tych danych, które są. Co najlepsze XSLT można stosować i po stronie przeglądarki i serwera. Wynik jest taki, że plik jest jeden, user ma dokładnie takie opcje jakie mieć powinien a przez łącze wysyłamy minimum danych. Serwer też jest odciążony.
Mogę to lepiej opisać jak ktoś chce.