•  

    Próbuję stworzyć własny OAuth serwer, ale nie jestem pewien czy to w jaki sposób chciałbym zbudować bazę danych ma jakiś większy sens, a także tego, czy dobrze rozumiem sposób, w jaki miałyby być obsługiwane poszczególne sposoby autoryzacji użytkowników / klientów.

    Aktualnie mam w ten sposób wyglądający schemat bazy danych:
    https://i.imgur.com/CHuwz5f.png
    Chciałbym, żeby ten serwer autoryzacyjny wspierał obecnie trzy sposoby autoryzacji: Authorization Code, Client Credentials oraz Resource Owner Password Credentials.

    1. Authorization Code

    pokaż spoiler Użytkownik korzysta z aplikacji X. Klika, że chciałby się zalogować przy użyciu mojego serwera autoryzacyjnego Y. Aplikacja X wysyła go do logowania na stronie Y (response_type=code). Użytkownik loguje się na stronie Y, klika że zezwala aplikacji X na dostęp do jego danych. Y wysyła go pod redirect_uri z wygenerowanym auth_codem. Aplikacja X wysyła zapytanie po access_token korzystając z otrzymanego auth_code. W odpowiedzi aplikacja X otrzymuje: access_token i refresh_token. Od teraz każdy request do resource serwerów aplikacja X będzie wysyłała z access_tokenem danego użytkownika. Jeśli access_token wygaśnie, aplikacja X odświeża go korzystając z refresh_tokenu.


    2. Client Credentials

    pokaż spoiler Ten flow w teorii miałby być wykorzystywany tylko wewnątrz mojej aplikacji. Powiedzmy, że jeden z mikroserwisów przy uruchomieniu wysyła zapytanie o token (response_type=client_credentials). W odpowiedzi otrzymuje access_token, który zawiera informacje o dostępnych oauth_scopes i oauth_resource_servers. Jeśli access_token wygaśnie, po prostu jeszcze raz wysyła zapytanie o niego - w końcu i tak ma cały czas dostęp do client_id i client_secret, a żadna dodatkowa akcja nie jest wymagana.


    3. Resource Owner Password Credentials

    pokaż spoiler Użytkownik loguje się w mojej aplikacji korzystając z emaila i hasła. Jego zapytanie trafia do API. API jest klientem, który posiada grant_type password. API wysyła zapytanie do serwera autoryzacyjnego Y (response_type=password) z emailem i hasłem użytkownika. W odpowiedzi dostaje access_token i refresh_token.


    ---

    W przypadku 1. i 3., access_token jest powiązany z kontem użytkownikiem. Zakładając, że miałby zawierać informacje o oauth_scopes, do których ma dostęp, byłyby to elementy wspólne między uprawnieniami użytkownika oraz klienta.

    W przypadku 2., access_token nie miałby żadnych informacji na temat użytkownika.

    ---

    Jak w takiej sytuacji powinna wyglądać obsługa ról użytkownika? Ok, mamy te oauth_scopes przypisane do klienta i do konta użytkownika, ale one chyba bardziej definiują dostęp do konkretnych zasobów. Co z rolami typu admin / menedżer / etc, definiującymi np. do jakich podstron klient powinien mieć dostęp?

    Jak powinna wyglądać autoryzacja zapytań w mikroserwisach? Przeglądarka użytkownika komunikuje się z API. API ma dostęp do kilku innych mikroserwisów. Co, jeśli te mikroserwisy komunikują się z innymi, które są gdzieś jeszcze bardziej zagnieżdżone? API powinno mieć do nich dostęp? Czy API powinno mieć dostęp tylko do mikroserwisów, z którymi się komunikuje bezpośrednio? Co wtedy ze scopem? W końcu użytkownik ma swoje oauth_scopes, API ma swoje i wyodrębniamy tylko wspólne elementy, więc te głębiej zagnieżdżone mikroserwisy mogą już nie znać wszystkich uprawnień użytkownika.

    Pewnie o czymś zapomniałem, więc jeśli ktoś miałby jakieś inne sugestie / uwagi / cokolwiek, byłbym wdzięczny!

    #webdev #javascript #nodejs
    pokaż całość

    +: lubie-sernik, g.......l +2 innych
    •  

      @oMatej: nie zobaczyłem tagów javascript i nodejs, dlatego podesłałem Ci tę bibliotekę, sorry :) Ja używając tej biblioteki zaimplementowałem u siebie sytuacje 3. z Twojego opisu. Ze względu na to, że użytkownik loguje się do swojego konta, to w ogóle nie skorzystałem ze scope - nie była mi potrzebna ta funkcjonalność.

      Co do ról użytkownika, to oauth2 tego nie obsługuje. Role i dostęp do poszczególnych akcji to ACL - powinna to być osobna klasa/plugin/mikroserwis. Role != scopes.

      Jeżeli chodzi o komunikacje między mikroserwisami, to ja zrealizowałem to w ten sposób że takie wewnętrzne requesty mają nagłowek Authorization o wartości: Internal LosowyTokenTrzymanyWAplikacji. Gdy dostaję zapytanie z takim nagłówkiem to wiem, że jest to zaufane zapytanie z innego mikroserwisu. Do tego można dodać jeszcze walidacje po IP i mamy bajlando :) Można to zrobić przez oAuth2, no ale KISS ( ͡° ͜ʖ ͡°)
      pokaż całość

    •  

      @Zaszczyk: tak, wiem, że OAuth nie powinien handlować rolami. Ale chciałbym umieścić je również w access_tokenie, żeby przeglądarka użytkownika też miała do nich dostęp, a przy okazji pozostałe mikroserwisy nie musiały odpytywać o role bazy danych przy każdym zapytaniu.

      Jeśli chodzi o komunikację wewnętrzną - ok, przekazujesz jakiś tam token jako nagłówek. Ale co teraz z tokenem użytkownika? Jakiś głębiej zagnieżdżony mikroserwis w ogóle go nie dostaje? Więc zakładasz, że "API" odfiltruje użytkowników, którzy np. nie mają uprawnień do wykonywania jakichś operacji w mikroserwisie X? Czy może po prostu wysyłasz go jako osobny parametr? pokaż całość

    • więcej komentarzy (4)

  •  

    Mamy może na wykopie jakichś ekspertów od Electrona? Tak siedzę nad tym i nie mam pomysłu w jaki sposób rozwiązać kwestię komunikacji / reakcji okna "A" na zdarzenie w oknie "B". Stworzyłem sobie klasę Window, która ma pochodne MainWindow i AuthWindow. Chciałbym, żeby zarządzanie nimi odbywało się w jakiejś głównej klasie (Application), która działa na app.on('ready').

    Przypuśćmy sytuację: Ktoś uruchamia aplikację. Wyświetla mu się okno MainWindow, gdzie klika przycisk "Zaloguj z Google". Okno MainWindow zostaje ukryte i wyświetla mu się okno AuthWindow, gdzie musi wyrazić zgodę na korzystanie z konta Google. Po odpowiedzi od Google wyświetla mu się ponownie MainWindow, a AuthWindow zostaje zamknięte.

    Reakcję na kliknięcie przycisku można rozwiązać za pomocą eventu ipc (i wtedy też ukryć MainWindow i stworzyć AuthWindow). Ale co ze zdarzeniami typu 'close', 'ready-to-show', danego okna?
    W tej głównej klasie ciężko byłoby nasłuchiwać na event this.authWindow.window.on('close', () => this.mainWindow.show()), skoro this.authWindow.window byłoby niezdefiniowane w momencie uruchamiania aplikacji.

    Teoretycznie mogę do każdego obiektu klasy z oknem przekazać this głównej klasy, która byłaby rozszerzeniem EventEmittera. Wtedy w klasie z oknem mógłbym zrobić coś w stylu this.window.on('close', () => this.app.emit('close-authWindow')), by następnie w głównej klasie obsłużyć this.on('close-authWindow', () => this.mainWindow.show()).

    Ewentualnie klasy Window mogłyby być rozszerzeniem EventEmittera, tworzyć ich instancje już na starcie aplikacji (żeby móc nasłuchiwać na wysyłane przez te eventy; wtedy w klasie okna this.window.on('close', () => this.emit('close-authWindow))), a dopiero w jakiejś funkcji init() tworzyć electronowe BrowserWindow.

    Tylko czy którekolwiek z tych rozwiązań ma sens i jest w ogóle poprawne? Może w ogóle powinno to być rozwiązane jakoś kompletnie inaczej? Tylko jak?

    #webdev #nodejs #javascript
    pokaż całość

    +: Cronox
  •  

    To się stanie ( ͡° ͜ʖ ͡°)
    #bukmacherka

    źródło: i.imgur.com

  •  

    Mam kilka pytań przede wszystkim do osób bawiących się Reactem i Reduxem ( ͡° ͜ʖ ͡°)

    1. Co brać pod uwagę decydując o tym, czy coś powinno być w reduxowym storze, czy po prostu jako state w komponencie?

    2. Jak Waszym zdaniem powinna wyglądać struktura reducera/ów, dla którego/ych mielibyśmy akcje typu: wyświetl listę produktów, zlicz liczbę produktów, wyświetl produkt, dodaj/edytuj/usuń produkt?

    Obecnie mam coś w stylu:
    productsReducer = {
    isFetching: false,
    productsPerPage: 15,
    amountProducts: null,
    item: {},
    items: []
    }


    Nie jestem pewien przede wszystkim sensowności tego pojedynczego produktu (item).

    Teoretycznie wyświetlając jeden element mógłbym pobierać jego dane z tabeli items, ale przy pojedynczym produkcie wyświetlam dużo więcej informacji (ze względu na relacje 1:n w bazie) niż w ich liście (oczywiście mogę przechowywać to wszystko również w liście, ale nie wiem, co byłoby lepszym rozwiązaniem?).

    A może pojedynczy produkt powinien być w ogóle w osobnym reducerze?

    #webdev #react
    pokaż całość

    +: Cronox
  •  

    Czy ktoś z Was miał może okazję bawić się w przesyłanie obrazu z kamerki na zasadzie jeden host, wielu odbiorców?

    Najprostszym rozwiązaniem wydawały mi się websockety, gdzie ze streamu z getUserMedia wyodrębniłem pojedyncze klatki, które były przesyłane poprzez serwer do innych odbiorców. Przy większej liczbie odbiorców kończyło się to niestety lagami.

    Jedynym sensownym rozwiązaniem w przypadku tego typu problemu jest WebRTC?
    Jak to połączyć z Node? Jako, że korzystam z biblioteki socket.io, próbowałem użyć socket.io-p2p, ale za nic nie mogę zrozumieć na jakiej zasadzie miałaby ona działać, a i w Internetach nie ma jakoś zbyt wielu przykładów jej użycia.

    Chodzi mi o działanie typu: wchodzi host => tworzy się pokój => wysyła obraz do klienta(ów) dołączających do pokoju.

    #nodejs #webdev
    pokaż całość

...to tylko najnowsze aktywności użytkownika oMatej

Zobacz wszystkie dodane znaleziska, komentarze i wpisy korzystając z menu powyżej.

Osiągnięcia (2)