/ / Architektura / Wyzwania techniczne w obsłudze uwierzytelniania / uprawnień w eliksirach Kanały / gniazda - websocket, eliksir, struktura feniksowa, kanały feniksowe

Architektury / Techniczne wyzwania w obsłudze uwierzytelniania / pozwoleń w kanałach / gniazdach Elixir - websocket, eliksir, struktura feniksowa, kanały feniksowe

Tak więc zdecydowałem się napisać ponownie aplikację, którą piszę w Node.js do Elixir, ze względu na całą dodatkową złożoność pracy z Node, że Eliksir jest dostarczany bez opakowania.

Mój problem był czymś, czego nie miałem racji w Node i staje się tak skomplikowany w Elixir i nie jestem do końca pewny, jak go podejść.

Próbuję odtworzyć wiele z tego, jak działa Discorduprawnienia. Zasadniczo buduję system CRM, z różnymi rolami, takimi jak "Sales Manager", "Sales", "Customer Service Rep" itd ... Ale wszyscy są w stanie robić różne rzeczy na podstawie ich "roli".

Niektóre rzeczy, które muszę zrobić, to móc zaktualizowaćzezwolenie w locie na osobę lub rolę. Być może rola "Sales Managera" nie może spojrzeć na dane finansowe firmy, takie jak "Księgowy", ale musimy dać tej konkretnej osobie dostęp na kilka dni lub mam "przedstawiciela działu obsługi klienta" i nadajemy tej roli możliwość dodawania rzeczy do kalendarza. Chciałbym również mieć możliwość zabijania sesji.

Jest kilka sposobów, które widziałem na forach Elixir, takich jak:

  • Używając Guardiana, naprawdę chcę polubić tokeny iPomyśl, że nie trzeba trafiać do bazy danych za każdym razem, gdy brzmi wspaniale, ale nie uważam tego za praktyczne. Chyba że istnieje dobre rozwiązanie do aktualizacji żetonów w locie, których nie znalazłem.
  • Podarowanie każdej osobie własnego procesu i sprawiedliwegozabij i rozpocznij proces zmian wraz z nowymi zmianami. Wydaje się to całkiem miłe, ale raczej nie zabijam procesów, chyba że istnieje rzeczywisty błąd, myślę, że to rozwiązanie przyniesie duże problemy, takie jak śledzenie problemów.Ale nie jestem dostatecznie zaznajomiony, aby wiedzieć, czy to rzeczywiście może powodować problemy, lub jeśli jest to złe rozwiązanie z innych powodów.
  • Użyj Guardiana z Guardian_DB, który następnie pokonujecel używania tokenów, ale przynajmniej mam sesję, którą można śledzić Jedynym moim problemem jest to, że planuję używać load-balancera, więc jeśli zginie połączenie z gniazdem, mogę ponownie połączyć się z tym samym serwerem i jestem nie wiesz, jak to zrobić z tokenami lub jeśli do samego gniazda dołączona jest sesja, nie jest to jednak tak duża kwestia i jest bardzo zbliżona do tego, co miałem z Node.js.
  • Użyj Redisa, którego chciałbym trzymać z daleka, inastępnie zaktualizuj dane sesji w Redis na podstawie user_id, gdy pojawią się aktualizacje i uderzaj Redis przy każdym żądaniu, aby sprawdzić, czy użytkownik ma uprawnienia. Mam zamiar umieścić to na wielu serwerach w końcu, co oznacza, że ​​ETS nie jest opłacalne, chyba że mogę ładować-zbalansować połączenia z gniazdem tak jak mogłem w Node.js.

Więc domyślam się, że moje pytania

  • Czy mogę dołączać sesje do gniazd? Czy to zły pomysł?
  • Czy nadal powinienem używać tokena i po prostu użyć Redis do sprawdzenia tokena przy każdym żądaniu?
  • Czy token jest wciąż lepszym wyborem niż sesja?
  • Czy istnieje o wiele lepsze / łatwiejsze rozwiązanie, o którym nawet nie wspomniałem?

Przykro mi, że to było bardzo pociągające i długie, nigdy nie musiałem robić czegoś profesjonalnie związanego z tym projektem i jestem całkiem nowym użytkownikiem Elixir.

Odpowiedzi:

1 dla odpowiedzi № 1

Kanały Phoenix są stateful. Możesz umieścić dane w pliku assigns pole i pozostaje tam przez czas połączenia. Tam zazwyczaj umieszczasz swój user_id po uwierzytelnieniu użytkownika przy dołączaniu.

Używam również przypisań kanałów do przechowywania stanu klienta, który jest mi potrzebny na serwerze.

WRT do roli do pytania o uprawnienia, ja "mrobiąc dokładnie to. To, co robię, to ładowanie obciążenia z uprawnieniami do roli z bazy danych podczas uruchamiania i budowanie z nimi sklepu ETS. Możesz zrobić to samo za pomocą zadania lub serwera GenServer. Jeśli uprawnienia zmieniają się dla danej roli, aktualizuję bazę danych i tabelę ETS.

Mój model użytkownika obsługuje listę ról dla każdego użytkownika.

Kiedy potrzebuję zweryfikować uprawnienia dla danego użytkownika, wywołuję api podobny model uprawnień Permission.has_permission?("create-room", user, scope). Mam dwa poziomy uprawnień, globalne i na pokój. Do tego służy zakres.