Z mojego doświadczenia wynika, że prawdziwe pytanie w większości sprowadza się do tego, czy wystąpią jakiekolwiek ograniczenia dostępu specyficzne dla użytkownika.
Załóżmy na przykład, że projektujesz schemat społeczności i umożliwiasz użytkownikom przełączanie widoczności ich profilu.
Jedną z opcji jest trzymanie się flagi profilu publicznego/prywatnego i trzymanie się ogólnych, zapobiegawczych kontroli uprawnień:„users.view” (wyświetla użytkowników publicznych) vs, powiedzmy, „users.view_all” (wyświetla wszystkich użytkowników, dla moderatorów) .
Inny obejmuje bardziej wyrafinowane uprawnienia, możesz chcieć, aby mogli konfigurować rzeczy, aby mogły być (a) widoczne dla wszystkich, (b) widoczne dla ich ręcznie wybranych znajomych, (c) całkowicie prywatne i być może (d ) widoczne dla wszystkich z wyjątkiem ich ręcznie wybranych bozos. W takim przypadku musisz przechowywać dane właściciela/dostępu dla poszczególnych wierszy i będziesz musiał mocno wyabstrahować niektóre z tych rzeczy, aby uniknąć materializacji przechodniego zamknięcia gęstego, zorientowanego grafu.
Przy każdym podejściu zauważyłem, że dodatkowa złożoność edycji/przypisania ról jest równoważona przez łatwość/elastyczność w przypisaniu uprawnienia do poszczególnych elementów danych i że najlepiej działają następujące elementy:
- Użytkownicy mogą mieć wiele ról
- Role i uprawnienia połączone w tej samej tabeli z flagą, aby je rozróżnić (przydatne podczas edycji ról/uprawnień)
- Role mogą przypisywać inne role, a role i uprawnienia mogą przypisywać uprawnienia (ale uprawnienia nie mogą przypisywać ról) z tej samej tabeli.
Wynikowy zorientowany wykres można następnie wyciągnąć w dwóch zapytaniach, zbudowanych raz na zawsze w rozsądnym czasie przy użyciu dowolnego używanego języka i buforować w Memcache lub podobnym do późniejszego użycia.
Od tego momentu pobranie uprawnień użytkownika jest kwestią sprawdzenia, jakie role ma on, i przetworzenia ich za pomocą wykresu uprawnień w celu uzyskania ostatecznych uprawnień. Sprawdź uprawnienia, sprawdzając, czy użytkownik ma określoną rolę/uprawnienie, czy nie. A następnie uruchom zapytanie/wyślij błąd na podstawie tego sprawdzenia uprawnień.
Możesz rozszerzyć sprawdzanie o poszczególne węzły (np. check_perms($user, 'users.edit', $node)
dla "może edytować ten węzeł" vs check_perms($user, 'users.edit')
dla "może edytować węzeł"), jeśli zajdzie taka potrzeba, a będziesz mieć coś bardzo elastycznego/łatwego w użyciu dla użytkowników końcowych.
Jak powinien zilustrować przykład otwierający, uważaj na zbytnie kierowanie się w stronę uprawnień na poziomie wiersza. Wąskie gardło wydajności polega w mniejszym stopniu na sprawdzaniu uprawnień poszczególnych węzłów, niż na pobieraniu listy prawidłowych węzłów (tj. tylko tych, które użytkownik może przeglądać lub edytować). Odradzałbym wszystko poza flagami i polami user_id w samych wierszach, jeśli nie jesteś (bardzo) dobrze zorientowany w optymalizacji zapytań.