2017-06-17 50 views
6

Mamy architekturę usług mikro i dyskutujemy o tym, jak ujawnić klientowi błędy wewnętrzne.Dobre praktyki w celu propagowania błędów za pośrednictwem usług mikroprzedsiębiorstw

Oto przykład:

Załóżmy mamy 3 usługi, serwis A, B i C. Kiedy klient wysyła żądanie do usługi, która jest publiczna, ta usługa wysyła żądanie do pokoi B który wysyła żądanie do usługi C (które są wewnętrzne i wymagają uwierzytelnienia, ale poświadczenia są przechowywane wewnętrznie, podobnie jak zmienne środowiskowe, nie są wysyłane przez klienta).

I z jakiegoś powodu komunikacja między B i C otrzymuje 401 (może być 422, 403 lub jakikolwiek błąd związany z klientem), co oznacza, że ​​żądanie nie było autoryzowane.

Coś takiego: enter image description here

Komunikacja pomiędzy B i C jest wewnętrzny, użytkownik nie wie o tych usług. Czy powinienem ujawnić naszą wewnętrzną strukturę wysyłając 401 do klienta? Czy to nie wina klienta? Czy powinienem wysłać 500?

+1

Jeśli nie jest to błąd użytkownika, to 5xx jest prawidłowym zakresem kodu odpowiedzi. –

+0

@OliverCharlesworth Zgadzam się z Tobą. Czy powinienem zarejestrować ten błąd wewnętrznie i nie ujawniać żadnych informacji użytkownikowi? co myślisz? –

+2

To zależy. Jednak generalnie uważa się, że nie można ujawnić szczegółów błędów wewnętrznych (takich jak ślady stosu) użytkownikowi (zarówno z punktu widzenia UX, jak i bezpieczeństwa). Co najwyżej, niektóre wiadomości, takie jak "500 Server Error - Twój unikalny identyfikator błędu to 123456", który pozwala na późniejsze skorelowanie użytkownika z identyfikatorem w dziennikach błędów. –

Odpowiedz

7

Lepiej unikać bezpośredniego ujawniania statusu 500, ale w niektórych przypadkach jest to konieczne. Użytkownik pracuje z twoim systemem, a nie z określoną usługą, a dla niego nie ma znaczenia, co jest w środku. Implementacja wewnętrznego systemu może być różna, ale interakcja użytkownika może pozostać taka sama.

Let's A będzie na przykład usługą e-commerce, B - usługą rozliczeniową i C - bramą rozliczeniową. Użytkownik kupuje produkt za pośrednictwem A, który wysyła żądanie fakturowania do B, a B komunikuje się z C, aby wykonać transakcję. 401 między B i C może być z różnych powodów. Jeśli jest to po prostu problem z wewnętrzną konfiguracją (brak zaktualizowanego hasła, wygasłego certyfikatu itd.), Jest to wewnętrzny błąd systemowy i musisz poinformować użytkownika, że ​​usługa jest teraz niedostępna lub coś w tym stylu, nie przekazując oczywiście wszystkich wewnętrznych szczegółów błędu. W tym przypadku możesz użyć kodu 5xx. Być może serwis B może skierować żądanie do jakiejś kolejki i powiedzieć serwisowi A, że wszystko jest w porządku, twoja prośba zostanie przetworzona później. Ale jeśli dzieje się tak, ponieważ użytkownik próbuje użyć złej karty kredytowej lub nie ma wystarczającej ilości pieniędzy (nieautoryzowane żądanie) A musi pokazać prawidłową wiadomość i kod odpowiedzi 4xx.

Ogólnie rzecz biorąc, usługa udostępnia zasoby i nie ma znaczenia, ile wewnętrznych lub zewnętrznych usług, baz danych, źródeł danych itp. Znajduje się za nimi. Być może 401 między B i C oznacza dla B przejście do służby D (C alternate), a serwis A nie powinien wiedzieć o 401 w ogóle. Zależy to od tego, co musisz pokazać użytkownikowi i jak radzić sobie z różnymi przypadkami.

2

Twój schemat nie ma większego sensu. Połączenie przychodzące nie wynosi 200, dopóki nie powróci do użytkownika pomyślnie po wywołaniu wszystkich wewnętrznych usług.

Jeśli autoryzacja między B i C jest wewnętrzna (autoryzacja z serwera do serwera), to wystąpił błąd wewnętrzny, a 502 jest rozsądnym wyborem, aby powrócić do A. Oczywiście, możesz spróbować ponownie na serwerze A, jak masz 502 z B, ale to nie ma sensu, ponieważ jest to wygasły token. Możesz więc zdecydować, że wewnętrzne 401 powinny zostać przeniesione z powrotem na A. Lub możesz znaleźć dołączenie metadanych do 502 części odpowiedzi na błąd, które wspomaga mechanizm ponownego próbowania. W każdym razie, uwierzytelnianie serwera serwera nie powinno zawieść, jeśli jest to prawidłowe połączenie.

Więc ... jeśli uwierzytelnianie C działa na tokenie dostarczonym przez użytkownika, to uwierzytelnianie użytkownika zakończyło się podczas połączenia (rzadko, ale zdarza się) - w tym przypadku token powinien zostać rozszerzony w innym miejscu w systemie przed to połączenie (prawdopodobnie w wywołaniu A do SSO). Ale tak nie było, więc zwróć 401 do miejsca, w którym aplikacja przekierowuje na stronę logowania.