2013-04-08 4 views
6

나는 빌딩이 a previous discussion I had with Jon Skeet입니다. 다음과 같이클라이언트에서 생성 한 GUID를 신뢰할 수없는 이유는 무엇입니까? PK를 클라이언트 GUID와 서버 GUID의 조합으로 처리하면 아무 것도 해결되지 않습니까?

내 시나리오의 요지는 다음과 같습니다

  • 클라이언트 응용 프로그램이 데이터베이스에 유지해야 할 새로운 'PlaylistItem'개체를 만들 수있는 기능이 있습니다.
  • 사용 사례에서는 PlaylistItem을 표시하기 전에 클라이언트가 서버의 응답을 기다릴 필요가 없도록 PlaylistItem을 만들어야합니다.
  • 클라이언트는 PlaylistItem에 대한 UUID를 생성하고 클라이언트에 PlaylistItem을 표시 한 다음 서버에 저장 명령을 실행합니다.

이 시점에서 나는 클라이언트에서 생성 된 UUID를 데이터베이스의 개체의 PK로 사용하는 것이 좋지 않다는 것을 알고 있습니다. 그 이유는 악의있는 ​​사용자가 생성 된 UUID를 수정하고 내 DB에서 PK 충돌을 강제 할 수 있기 때문입니다.

PlaylistItem에서 PK 충돌을 발생시키는 피해를 줄이기 위해 클라이언트 생성 UUID와 서버 생성 GUID의 두 ID의 복합체로 PK를 정의했습니다. 서버 생성 GUID는 PlaylistItem의 재생 목록 ID입니다.

지금 당분간이 솔루션을 사용하고 있지만 클라이언트 ID를 단순히 신뢰하는 것보다 내 솔루션이 더 나은 이유는 무엇인지 이해가 안됩니다. 사용자가 다른 사용자의 PlaylistItem 객체와 PK 콜리 손을 강제로 수행 할 수 있다면 해당 사용자의 PlaylistId를 제공 할 수 있다고 가정해야한다고 생각합니다. 그들은 여전히 ​​콜리 손을 강요 할 수 있습니다.

그래서 ... 예. 이런 식으로하는 올바른 방법은 뭔가요? 클라이언트가 UUID를 만들도록 허용하고, 서버는 성공적으로 저장 될 때 엄지 손가락을 위/아래로줍니다. 충돌이 발견되면 클라이언트 변경 사항을 되돌리고 감지 된 collison을 알립니다.

답변

2

좋은 솔루션이 될 것입니다 다음 인용하면 샘 뉴먼의 "Building Microservices" :

호출 시스템은 아마도 파일이 모든 데이터를 배치 할 수있는 위치에 전달하여 BatchRequest을 POST 것이다. 고객 서비스는 요청이 수락되었지만 아직 처리되지 않았 음을 나타내는 HTTP 202 응답 코드를 반환합니다. 이 요청이 귀하의 경우 그래서

을 성취되었음을 나타내는 만든 201 를 검색 할 때까지 호출 시스템은 다음 리소스 대기를 폴링 수, 당신은 서버에 POST하지만 바로 같은 응답을 얻을 수있다 "나는 절약 할 수 PlaylistItem과 나는 그 ID가이 하나가 될 것이라고 약속한다. " 클라이언트 (및 사용자)는 서버 (API조차도 아닐지라도 API로부터 메시지를받은 일부 백그라운드 프로세서)가 엔티티를 저장할 때까지 무거운 로직을 처리, 검증 및 다른 작업을 수행하는 데 시간이 걸리는 동안 계속할 수 있습니다. 앞에서 설명한 것처럼 API는 요청의 상태에 대해 GET 끝점을 제공 할 수 있으며 클라이언트는 오류 요청시 해당 요청을 폴링하고 그에 따라 작동 할 수 있습니다.

1

사용자 은 클라이언트에서 생성 된 UUID 또는 이와 유사한 전역 고유 식별자를 서버에서 신뢰합니다. 그걸 현명하게해라.

대부분의 테이블/컬렉션은 userId를 보유하거나 FK를 통해 userId와 연결할 수 있습니다.

삽입을 수행하고 악의적 인 사용자가 기존 키를 사용하는 경우 기록/문서가 이미 있으므로 삽입이 실패합니다.

업데이트를 수행중인 경우 로그인 한 사용자가 해당 레코드를 소유하고 있거나 (예 : 관리 사용자) 업데이트를 승인했는지 확인해야합니다. 순수한 소유권이 적용되는 경우 (즉, 관리자가 아닌 시나리오) 레코드/문서를 찾으려면 where 절에 Id와 userId가 모두 포함됩니다. id가 고유하게 하나의 레코드/문서를 찾을 것이므로 기술적으로 userId는 where 절에서 중복됩니다. 그러나 userId를 추가하면 레코드가 악의적 인 사용자가 아닌 업데이트를 수행하는 사용자에게 속하게됩니다.

암호화 된 토큰이나 서버가 userId를 확인하기 위해 암호 해독하는 세션이 있다고 가정합니다. 클라이언트가 제공하지 않는 경우에는 그렇지 않은 것이 분명 안전하지 않습니다.