Buduję off z a previous discussion I had with Jon Skeet.Dlaczego nie mogę ufać GUID wygenerowanemu przez klienta? Czy traktowanie PK jako złożonego klienta-GUID i GUID serwera rozwiązuje cokolwiek?
Istotą mojego scenariusza jest następująca:
- aplikacja Klient ma możliwość tworzenia nowych obiektów „PlaylistItem”, które muszą być utrwalone w bazie danych.
- Przypadek użycia wymaga, aby element PlaylistItem został utworzony w taki sposób, aby klient nie musiał czekać na odpowiedź z serwera przed wyświetleniem elementu PlaylistItem.
- Klient generuje identyfikator UUID dla PlaylistItem, pokazuje PlaylistItem w kliencie, a następnie wydaje polecenie zapisu na serwerze.
W tym momencie rozumiem, że niewłaściwym zwyczajem byłoby używanie identyfikatora UUID wygenerowanego przez klienta jako PK obiektu w mojej bazie danych. Powodem tego jest to, że złośliwy użytkownik może modyfikować wygenerowany identyfikator UUID i wymuszać kolizje PK na moim DB.
Aby złagodzić wszelkie szkody, które mogą powstać w wyniku wymuszenia kolizji PK w PlaylistItem, zdecydowałem się zdefiniować PK jako połączenie dwóch identyfikatorów - generowanego przez klienta identyfikatora UUID i wygenerowanego przez serwer identyfikatora GUID. Identyfikator GUID generowany przez serwer jest identyfikatorem listy odtwarzania PlaylistItem.
Od pewnego czasu używam tego rozwiązania, ale nie rozumiem, dlaczego moje rozwiązanie jest lepsze niż zaufanie do identyfikatora klienta. Jeśli użytkownik jest w stanie wymusić kolizję PK z obiektami PlaylistItem innego użytkownika, to sądzę, że powinienem założyć, że może to być PlaylistId tego użytkownika. Mogą nadal wymuszać collisons.
Więc ... tak. Jaki jest właściwy sposób robienia czegoś takiego? Zezwalaj klientowi na utworzenie UUID, serwer daje kciuk w górę/w dół po pomyślnym zapisaniu. Jeśli zostanie wykryta kolizja, należy cofnąć zmiany klienta i wykryć wykrycie kolizji?