Why is it important to set the developer payload with in-app billing?


78

I'm using version 3 of the in-app billing API. I have a single, managed, non-consumable item. I have not released this feature in my app yet, so I want to decide on the purchase payload contents before there are any purchases.

From "Security Best Practices":

Set the developer payload string when making purchase requests

인앱 결제 버전 3 API를 사용하면 Google Play에 구매 요청을 보낼 때 '개발자 페이로드'문자열 토큰을 포함 할 수 있습니다. 일반적으로이 구매 요청을 고유하게 식별하는 문자열 토큰을 전달하는 데 사용됩니다. 문자열 값을 지정하면 Google Play는 구매 응답과 함께이 문자열을 반환합니다. 이후에이 구매에 대해 쿼리 할 때 Google Play는 구매 세부 정보와 함께이 문자열을 반환합니다.

나중에 해당 사용자의 합법적 인 구매인지 확인할 수 있도록 애플리케이션에서 구매 한 사용자를 식별하는 데 도움이되는 문자열 토큰을 전달해야합니다. 소모성 품목의 경우 무작위로 생성 된 문자열을 사용할 수 있지만, 비 소모성 품목의 경우 사용자를 고유하게 식별하는 문자열을 사용해야합니다.

Google Play에서 응답을 받으면 개발자 페이로드 문자열이 구매 요청과 함께 이전에 보낸 토큰과 일치하는지 확인하세요. 추가 보안 예방 조치로 자신의 보안 서버에서 확인을 수행해야합니다.

바르게 또는 잘못, 내가 결정 하지 구매 검증을 수행하기 위해 서버를 설정하는 "더 보안 예방 조치"를 취할. 그리고 저는 구매 기록을 저장하지 않습니다. 저는 항상 청구 API를 호출합니다. 이 페이로드 확인을 수행해야하는 이유가 정말로 있습니까? 확인 API 자체는 항목을 구매 한 것으로보고하기 전에 사용자의 신원을 확실히 확인합니다. 공격자가 기기 (앱 또는 Google Play API)를 해킹 한 경우 추가 확인을 수행해도 이점이 없습니다. 쉽게 우회 할 수있는 장치의 사용자 ID 아니면 내가 생각하지 않는 이것을 할 이유가 있습니까?

답변:


70

기록을 보관하지 않으면받은 내용이 보낸 내용인지 확인할 방법이 없습니다. 따라서 개발자 페이로드에 무언가를 추가하는 경우 합법적이라고 믿거 나 (서명이 확인하는 경우 합리적인 가정) 완전히 신뢰하지 않고 참조로만 사용할 수 있지만 라이선스 상태 확인에는 사용할 수 없습니다. 예를 들어 사용자 이메일을 저장하는 경우 다시 입력하도록 요청하는 대신 값을 사용할 수 있습니다. 이는 사용자에게 약간 더 친숙하지만 앱이 없으면 중단되지 않습니다.

개인적으로 저는이 모든 '모범 사례'부분이 혼란스럽고 API가 실제로 수행해야하는 작업을 수행하도록하려고합니다. 구매는 Google 계정에 연결되어 있고 Play 스토어는 분명히이 정보를 저장하므로 구매 세부 정보에서이 정보를 제공해야합니다. 적절한 사용자 ID를 얻으려면 IAB API의 결함을 해결하기 위해 추가 할 필요가없는 추가 권한이 필요합니다.

간단히 말해, 자체 서버와 특별한 추가 기능 로직이 없다면 개발자 페이로드를 사용하지 마십시오. IAB v3 API가 작동하는 한 괜찮습니다 (불행히도이 시점에서 상당히 큰 'if'임).


4
처음 답변 한 지 1 년 반이 지난 후에도 여전히 같은 기분이 듭니까? 그 이후로 API에 대한이면에서 변경된 사항이 있는지 확실하지 않습니다. 현재 Google 문서를 신뢰한다고 말할 수 없습니다.
Alex Lockwood

6
여전히 IAP는 보안을 투명하게 제공해야하며 개발자 페이로드를 사용할 필요가 없어야한다고 생각합니다. 아마도 지금은 그렇 겠지만, 나는 꽤 오랫동안 그것을 보거나 사용하지 않았습니다. 내 앱은 여전히 ​​'새'IAP가 제공하지 않는 내 서버에서 추적 할 수있는 구매 알림을 제공하기 때문에 원래 IAP를 주로 사용합니다.
Nikolay Elenkov 2014

2
물론 서버에서 유효성을 검사 할 필요가 있다고 생각합니다. 사용자가 일종의 계정 식별자 (자신의 또는 3 자)로 "로그인"하지 않은 경우 V3는 매우 어렵게 만듭니다. API V2를 사용해 볼 수도 있지만 ... 2015 년 1 월 27 일에 인앱 결제 버전 2 서비스를 해제 할 계획입니다. 이후 사용자는 버전 2 API를 통해 더 이상 인앱 항목 및 구독을 구매할 수 없습니다. 사용자가 앱을 새 버전으로 업데이트 할 충분한 시간을 제공 할 수 있도록 2014 년 11 월까지 버전 3 API를 사용하도록 앱을 마이그레이션하는 것이 좋습니다.
inteist

@Nikolay Elenkov, 지금 당신의 제안은 무엇입니까? 이 모든 모범 사례가 Google 측에 있어야한다는 데 동의합니다.
stuckedoverflow

30

애플리케이션에서 구매 한 사용자를 식별하는 데 도움이되는 문자열 토큰을 전달해야합니다.

애플리케이션에서 휴대 전화가 연결된 Google 계정과 다른 고유 한 사용자 로그인 및 ID를 제공하는 경우 개발자 페이로드를 사용하여 구매를 한 계정 중 하나에 구매를 첨부해야합니다. 그렇지 않으면 누군가가 앱에서 계정을 전환하여 구매 한 항목의 혜택을받을 수 있습니다.

예 :

앱에 userA 및 userB에 대한 로그인이 있다고 가정합니다. 그리고 휴대 전화의 Android Google 계정은 X입니다.

  1. userA는 앱에 로그인하여 평생 회원권을 구매합니다. 구매 세부 정보는 Google 계정 X에 저장됩니다.
  2. userA는 로그 아웃하고 userB는 앱에 로그인합니다. 이제 userB는 Android Google 계정이 여전히 X이므로 평생 회원 자격의 혜택을받습니다.

이러한 오용을 방지하기 위해 구매를 계정에 연결합니다. 위의 예에서는 userA가 구매할 때 개발자 페이로드를 "userA"로 설정합니다. 따라서 userB가 로그인하면 페이로드가 로그인 한 사용자 (userB)와 일치하지 않으며 구매를 무시합니다. 따라서 userB는 userA가 구매 한 혜택을받을 수 없습니다.


좋은 대답입니다. 그러나 사용 로그인 메커니즘이 없다면 어떻게 될까요? 그럼 우리는 페이로드를 사용하지 않습니까?
tasomaniac

7
이 사용자 ID 문제에 대해 잠시 머릿속을 긁어 본 후, 당신이 지적하는 것이 페이로드 문자열의 실제 의도 일 수 있다고 생각합니다. Google 문서에서는 매우 잘 설명되어 있지 않습니다.
Pooks

따라서, 사용자의 Gmail은 트릭을 할 것입니다 및로 사용할 수 있습니다developerPaylod
사미 Eltamawy

3
@keybee 그게 바로 요점입니다. 언급하신 경우, 개발 페이로드를 사용하지 않으면 인앱 결제가 "이미이 항목이 있습니다"를 반환 할 때 userB 프리미엄 기능을 제공해야합니다 (이 항목을 만든 사용자 B인지 알 수있는 방법이 없기 때문). 처음에 구매). userB가 userA가 구매 한 기기에서 구매해야하는 경우 userB는 자신의 Google 계정으로 전환하여 구매해야합니다.
therealsachin

3
@therealsachin 나는 이것을 얻지 만, 내 서버를 확인하고 userB를 차단하면 Google Play가 먼저 기본 계정으로 확인하기 때문에 다른 계정으로 멤버십을 구매할 기회가 없으므로 동일한 장치에서 두 명의 사용자가 그렇지 않습니다. 작업. 그러나 이것은 userA가 어떤 이유로 계정이 하나 더 필요한 경우에만 문제가 될 수 있습니다. 그는 다른 페이로드를 사용하더라도 동일한 Google 계정으로 다시 구매할 수 없습니다. -이상적인 경우는 새로운 페이로드의 경우 구독을 다시 구입할 수 있어야한다는 것입니다.
keybee 2015-08-28

21

개발자 페이로드 처리에 대한 또 다른 접근 방식이 있습니다. Nikolay Elenkov가 말했듯이 사용자 ID를 요구하고 앱에 대한 사용자 프로필에 대한 추가 권한을 설정하는 것은 너무 많은 오버 헤드이므로 이것은 좋은 접근 방식이 아닙니다. In-App Billing v3 샘플에서 최신 버전의 TrivialDrive 샘플 앱에서 Google이 말하는 내용을 살펴 보겠습니다.

  • 경고 : 구매를 시작하고 여기에서 확인할 때 임의의 문자열을 로컬에서 생성하는 것이 좋은 방법처럼 보일 수 있지만 사용자가 한 기기에서 항목을 구매 한 다음 다른 기기에서 앱을 사용하는 경우에는 실패합니다. 다른 장치는 원래 생성 한 임의의 문자열에 액세스 할 수 없습니다.

따라서 임의의 문자열은 다른 장치에서 구매 한 항목을 확인하려는 경우 좋은 생각이 아니지만 여전히 구매 응답을 확인하는 데 좋지 않다고 말하지 않습니다. 나는 말하고 싶다-임의의 고유 문자열을 전송하여 구매를 확인하는 데에만 개발자 페이로드를 사용하고 환경 설정 / 데이터베이스에 저장하고 구매 응답에서이 개발자 페이로드를 확인하십시오. 활동 시작시 인벤토리 (인앱 구매)를 쿼리하는 경우-임의의 고유 문자열이 저장되지 않은 다른 기기에서 발생할 수 있으므로 개발자 페이로드를 확인하지 마세요. 그것이 내가 보는 방법입니다.


4
감사합니다.이 접근 방식을 구현하고 있습니다 (그리고 찬성했습니다 :). 좋은 타협처럼 들리기 때문에 설명 된대로 논리에 문제가 있다고 생각합니다. 구매시 페이로드 확인이 실패하면 Google Play는 여전히 사용자가 항목을 소유하고 있다고 생각하므로 앱을 다시 시작하면 인벤토리를 읽고 페이로드 확인없이 항목을 제공합니다. 한 가지 해결 방법은 구매시 페이로드 확인이 실패 할 경우 항목을 소비하는 것입니다.하지만 사용자의 돈을
빼앗아 서

장치 ID를 페이로드로 제공하면 "장치 별 라이선스"판매를 구현할 수 있습니다. 따라서 사용자가 한 장치에서 구매 한 경우 다른 장치에서 사용할 수 없습니다. 이것은 응용 프로그램의 정식 버전을 판매하는 데 유용 할 수 있습니다. 바이러스 백신.
bancer 2013-09-13

@Georgie 코멘트를 읽으십시오. 그렇지 않으면 이것이 나쁜 생각이라는 것을 알아내는 데 많은 시간을 할애 할 것입니다.
Halvor Holsten Strand

16

확인 방법에 따라 developerPayload . 두 가지 시나리오가 있습니다 : 원격 확인 (서버 사용)과 로컬 (장치에서).

섬기는 사람

developerPayload확인 을 위해 서버를 사용하는 경우 장치와 서버 모두에서 쉽게 계산할 수있는 임의의 문자열이 될 수 있습니다. 요청을 수행 한 사용자를 식별 할 수 있어야합니다. 모든 사용자 가정하면 해당 갖는다 accountIddeveloperPayload조합과 같이 계산 될 수있다 purchaseId이와 같은 (SKU 명) :

MD5(purchaseId + accountId)


장치

developerPayload 사용자 이메일이 아니어야합니다 . 이메일을 페이로드로 사용하지 않아야하는 좋은 예는 Google for Work 서비스입니다. 사용자는 계정과 연결된 이메일을 변경할 수 있습니다. 유일한 변함없는 것은accountId . 대부분의 경우 이메일은 괜찮지 만 (예 : Gmail 주소는 현재 변경할 수 없음) 미래를 위해 설계해야합니다.

여러 사용자가 동일한 장치를 사용할 수 있으므로 항목 소유자를 구별 할 수 있어야합니다. 장치 확인의 developerPayload경우 사용자를 고유하게 식별하는 문자열입니다. 예 :

MD5(purchaseId + accountId)


결론

일반적으로 developerPayload두 경우 모두 accountId. 나를 위해 그것은 모호함을 통한 보안 . MD5 (또는 다른 해싱 알고리즘) purchaseId는 계정의 ID를 사용하고 있음을 명시 적으로 표시하지 않고 페이로드를 더 무작위로 만드는 방법입니다. 공격자는 앱이 어떻게 계산되는지 확인하기 위해 앱을 디 컴파일해야합니다. 앱이 더 잘 난독 화되어 있다면.

페이로드는 보안을 제공하지 않습니다. . '장치'접근 방식으로 쉽게 스푸핑 될 수 있으며 '서버'검사에 아무런 노력을 기울이지 않아도됩니다. Google 게시자 계정 콘솔에서 제공되는 공개 키를 사용하여 서명 확인을 구현해야합니다.

* 이메일 대신 계정 ID 사용에 대한 필독 블로그 게시물입니다.


1
accountId는 무엇입니까? & accountId를 얻는 방법? 그 상세한 내용 (계좌를 전환하는 동안) 다수의 구글 플레이 계정 동일한 계정 아이디를 유지할 수있다 github.com/googlesamples/android-play-billing/issues/2
Sarath 쿠마

5

간단한 드라이브 샘플 작성자가 직접 제공 한 IAB v3에 대한 Google IO 비디오에서이 내용은 비디오 끝 부분에 간략하게 설명되어 있습니다. 예를 들어 공격자가 트래픽을 스니핑하고 성공적인 구매가 포함 된 패킷을 훔친 다음 자신의 장치에서 패킷을 재생하려고 시도하는 등 재생 공격을 방지하기위한 것입니다. 앱이 프리미엄 콘텐츠 (이상적으로는 서버에서)를 릴리스하기 전에 개발자 페이로드 (이상적으로는 서버에서)를 통해 구매자의 신원을 확인하지 않으면 공격자가 성공합니다. 패킷이 손상되지 않았기 때문에 서명 확인에서이를 감지 할 수 없습니다.

제 생각에는이 보호 기능은 클래시 오브 클랜 (어쨌든 사용자를 식별해야하기 때문에 페이로드가 자연스럽게 발생 함)과 같은 온라인 계정 연결이있는 앱, 특히 해킹이 단순한 현지화 된 불법 복제 사례 이외의 광범위한 효과로 멀티 플레이어 게임 플레이를 손상시키는 앱에 이상적이라고 생각합니다. . 반대로 클라이언트 측 해킹이 이미 프리미엄 콘텐츠를 잠금 해제 할 수 있다면이 보호 기능은 그다지 유용하지 않습니다.

(공격자가 페이로드를 스푸핑하려고하면 서명 확인이 실패합니다.)


사용자가 앱을 여는 동안 실시간 db에 저장되는 account_id, developer_payload 필드가있는 Google 로그인 및 실시간 데이터베이스와 함께 firebase를 사용할 수 있습니까 (오프라인 시설에 대한 추가 공유 환경 설정 포함)?
Dhaval Jotaniya

5

2018 년 후반 업데이트 : 공식 Google Play 결제 라이브러리는 의도적으로 developerPayload. 에서 여기 :

developerPayload 필드는 이전 구현과의 호환성을 유지하기 위해 유지되는 레거시 필드이지만 인앱 결제 제품 구매 페이지 ( https://developer.android.com/training/in-app-billing/purchase-iab -products.html ),이 필드는 인앱 결제와 관련된 작업을 완료 할 때 항상 사용할 수있는 것은 아닙니다. 그리고 라이브러리는 가장 업데이트 된 개발 모델을 나타내도록 설계 되었기 때문에 구현에서 developerPayload를 지원하지 않기로 결정했으며이 필드를 라이브러리에 포함 할 계획이 없습니다.

developerPayload에서 인앱 결제 로직의 중요한 구현에 의존하는 경우이 필드가 언젠가 (또는 곧) 지원 중단되므로이 접근 방식을 변경하는 것이 좋습니다. 권장되는 접근 방식은 자체 백엔드를 사용하여 주문에 대한 중요한 세부 정보를 확인하고 추적하는 것입니다. 자세한 내용은 보안 및 디자인 페이지 ( https://developer.android.com/google/play/billing/billing_best_practices.html )를 확인 하세요 .


이것은 나를위한 질문을 해결합니다 ... 그것은 사용되지 않기 때문에 사용해서는 안됩니다
smitty1

3

나는 이것으로 고생했다. Google Play 계정은 '관리되는'항목 중 하나만 소유 할 수 있지만 여러 기기를 보유 할 수 있기 때문에 (3 개 보유) '기기 당'을 판매하는 사람의 위 댓글은 작동하지 않습니다. 첫 번째 장치에 넣을 수 있고 다른 장치에는 넣을 수 없습니다. 프리미엄 업그레이드를 구입하면 모든 휴대폰 / 태블릿에서 작동합니다.

나는 사용자의 이메일 주소를 얻는다는 개념을 경멸하지만 다른 신뢰할 수있는 방법을 실제로 찾지 못했습니다. 따라서 계정 목록에서 "google.com"과 일치하는 첫 번째 계정 (예, 매니페스트에 추가 할 수있는 권한)을 가져온 다음 즉시 해시하여 더 이상 이메일 주소로 사용할 수 없지만 "충분히 고유 한 "토큰. 이것이 개발자 페이로드로 보내는 것입니다. 대부분의 사람들이 Google Play ID로 기기를 활성화하기 때문에 세 기기 모두 동일한 토큰을 받게됩니다 (각 기기에서 동일한 해시 알고리즘 사용).

여러 "사용자"가있는 KitKat에서도 작동합니다. (내 개발자 ID는 한 사용자, 내 테스트 ID는 다른 사용자, 각 사용자는 자신의 샌드 박스에 있습니다).

총 3 명의 사용자가있는 6 개의 장치에서 테스트했으며 각 사용자 장치는 동일한 해시를 반환했으며 다른 사용자는 모두 고유 한 해시를 사용하여 지침을 충족했습니다.

사용자의 이메일 주소를 저장하지 않고 코드에서 바로 전달되어 계정 이름을 해시 함수로 가져오고 해시 만 힙에 저장됩니다.

사용자의 개인 정보를 더욱 존중하는 더 나은 솔루션이있을 수 있지만 지금까지는 찾지 못했습니다. 앱이 게시되면 개인 정보 보호 정책에 사용자 이메일 주소를 사용하는 방법에 대한 매우 명확한 설명을 넣을 것입니다.


6
그것은 모두 훌륭하지만 여기에서 불필요한 과잉이 아닌 ACCOUNTS 권한이 필요합니다. 도대체 왜 구글은 구매를하기 위해 사용 된 계정의 해시를 만들 수 없었습니다. 그게 가장 깨끗한 해결책이 될 것입니다. 이제는 단순한 "깨진"것입니다.
inteist

이와 비슷한 작업을 수행했지만 이제 Android 6에서는 앱이 사용자에게 연락처 권한을 부여하도록 요청해야합니다. 이는 사용자가 앱을 처음 시작할 때 끔찍한 경험입니다. 대신 구매 복원 옵션을 구현할 수 있습니다. 또한 첫 번째 google.com 계정을 확보 한 경우 사용자가 휴대 전화에 둘 이상의 계정을 갖고 있고 계정을 재정렬하면 문제가 발생할 수 있습니다 (예 : 계정 A를 삭제 한 다음 나중에 다시 추가하지만 지금은 첫 번째 계정이 아님). . 드물게 발생하지만 발생합니다. 따라서 계정 선택 도구도 사용해야합니다! Yuch!
snark

1

이것은 종종 제품 정의 (귀하의 응용 프로그램)에 응답합니다. 예를 들어 구독의 경우. 동일한 사용자가 보유한 모든 장치에서 구독을 사용할 수 있습니까? 대답이 '예'인 경우. 우리는 페이로드를 확인하지 않았습니다.

소모품 용. 애플리케이션에서 구매하면 10 개의 가상 코인이 제공된다고 가정합니다. 사용자가이 코인을 다른 장치에서 사용할 수 있습니까? 한 장치에 4 개, 다른 장치에 6 개? 구매 한 기기에서만 작업하려면 예를 들어 자체 생성 된 문자열로 로컬에 저장된 페이로드를 확인해야합니다.

이러한 질문을 바탕으로 페이로드 검사를 구현하는 방법을 결정해야합니다.

문안 인사

산티아고

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.