2016-10-14 2 views
3

중앙 게임 서버에서 Google API를 통해 Android IAP를 확인하고 싶습니다.Java 서버 측 Android IAP 확인

이 부분에 대한 많은 정보가 있으며 마음이 날라 가고 있습니다. Google 개발자가되기 위해 25 유로를 지불하지 않았습니다. 작동 여부를 알 수 없기 때문입니다.

IAP가 만들어지면 JSON 개체가 반환됩니다. 이 개체는 purchaseTokenproductId (source)과 같은 여러 필드를 포함합니다.

다음 GET 요청을 통해 구입 한 제품에 대한 정보를 요청할 수 있음을 발견했습니다 : GET https://www.googleapis.com/androidpublisher/v2/applications/packageName/purchases/products/productId/tokens/token.

이 문제는 프로그램 할 수 있지만 직접 인증해야합니다. "이 요청에는 다음 범위의 인증이 필요합니다." (source). 여기가 내가 혼란스러워하기 시작한 곳입니다.

  1. 개발자 콘솔 (Link)을 통해 로그인 토큰을 만들어야합니다. 나는 어떤 타입인지 모른다. OAuth 또는 서비스 계정?
  2. 이 토큰은 수명이 짧습니다. 새로 고침해야 함

인터넷에서 발견 될 수있는 몇 가지 거대한 코드 조각이있을 수도 있고 그렇지 않을 수도 있지만 모두 부분적이고 문서화가 잘되어 있지 않습니다.

Java 용 Googles API 라이브러리 : link이 있습니다. 이 API는 이러한 모든 문제를 OAuth 및 토큰으로 해결할 것입니다. 그러나이 API를 작동시키는 방법을 알 수 없습니다.

아마도 그렇게 어렵지는 않을 것입니다. 그러나 그 방법에는 여러 가지가 있으며, 명확한 예를 찾을 수 없습니다.

TL : DR : Google Play IAP 서버 측을 인증해야합니다. 이를 위해 Googles Java API를 사용하고 싶습니다.

편집 :이 방법은 간단 할 수 있습니다. 원본 JSON과 JSON을 서버에 전달하는 것이 비대칭 서명 서버 측을 확인할 수 있기 때문에 훨씬 쉽습니다.

+0

다음은 도움이됩니다. https://stackoverflow.com/questions/35127086/android-inapp-purchase-receipt-validation-google-play/35138885#35138885 –

+0

나는 그것을 따라하려고했지만 API UI에는 완전 변경되었습니다. 그리고 토큰 새로 고침 문제에 대한 해결책은 포함되어 있지 않습니다. – kwantuM

답변

2

스칼라에서는 표준 Java 라이브러리를 사용하여 코드를 Java로 변환하는 것이 매우 간단합니다.

  • 먼저 서비스 계정이 필요합니다. Google 개발자 콘솔을 통해 만들 수 있습니다. 기본적으로 백엔드 서비스를 인증하고 토큰을 생성하는 데 사용할 생성 된 전자 메일을 다시 제공합니다.

  • 해당 계정이 생성되면 개인 키를 다운로드하라는 메시지가 나타납니다. JWT에 서명하는 것이 필요합니다.

  • Google에서 지정한 형식으로 JWT를 생성해야합니다. 참조 : https://developers.google.com/identity/protocols/OAuth2ServiceAccount#creatingjwt

  • 를 다음의 JWT와 함께, 당신은 액세스 토큰 액세스 토큰으로

  • 을 요청할 수 있습니다, 당신은 이제 당신의 구매

    /** Generate JWT(JSON Web Token) to request access token 
        * How to generate JWT: https://developers.google.com/identity/protocols/OAuth2ServiceAccount#creatingjwt 
        * 
        * If we need to generate a new Service Account in the Google Developer Console, 
        * we are going to receive a .p12 file as the private key. We need to convert it to .der. 
        * That way the standard Java library can handle that. 
        * 
        * Covert the .p12 file to .pem with the following command: 
        * openssl pkcs12 -in <FILENAME>.p12 -out <FILENAME>.pem -nodes 
        * 
        * Convert the .pem file to .der with the following command: 
        * openssl pkcs8 -topk8 -inform PEM -outform DER -in <FILENAME>.pem -out <FILENAME>.der -nocrypt 
        * 
        * */ 
        private def generateJWT(): String = { 
    
        // Generating the Header 
        val header = Json.obj("alg" -> "RS256", "typ" -> "JWT").toString() 
    
        // Generating the Claim Set 
        val currentDate = DateTime.now(DateTimeZone.UTC) 
        val claimSet =Json.obj(
         "iss" -> "<YOUR_SERVICE_ACCOUNT_EMAIL>", 
         "scope" -> "https://www.googleapis.com/auth/androidpublisher", 
         "aud" -> "https://www.googleapis.com/oauth2/v4/token", 
         "exp" -> currentDate.plusMinutes(5).getMillis/1000, 
         "iat" -> currentDate.getMillis/1000 
        ).toString() 
    
        // Base64URL encoded body 
        val encodedHeader = Base64.getEncoder.encodeToString(header.getBytes(StandardCharsets.UTF_8)) 
        val encodedClaimSet = Base64.getEncoder.encodeToString(claimSet.getBytes(StandardCharsets.UTF_8)) 
    
        // use header and claim set as input for signature in the following format: 
        // {Base64url encoded JSON header}.{Base64url encoded JSON claim set} 
        val jwtSignatureInput = s"$encodedHeader.$encodedClaimSet" 
        // use private key generated by Google Developer console to sign the content 
        val keyFile = Paths.get("<path_to_google_play_store_api.der>"); 
        val keyBytes = Files.readAllBytes(keyFile); 
    
        val keyFactory = KeyFactory.getInstance("RSA") 
        val keySpec = new PKCS8EncodedKeySpec(keyBytes) 
        val privateKey = keyFactory.generatePrivate(keySpec) 
    
        // Sign payload using the private key 
        val sign = Signature.getInstance("SHA256withRSA") 
        sign.initSign(privateKey) 
        sign.update(jwtSignatureInput.getBytes(StandardCharsets.UTF_8)) 
        val signatureByteArray = sign.sign() 
        val signature = Base64.getEncoder.encodeToString(signatureByteArray) 
    
        // Generate the JWT in the following format: 
        // {Base64url encoded JSON header}.{Base64url encoded JSON claim set}.{Base64url encoded signature} 
        s"$encodedHeader.$encodedClaimSet.$signature" 
        } 
    

의 유효성을 검사 요청을 할 수 당신은 JWT가 생성 된 것을 알면 다음과 같이 을 요청할 수 있습니다 :

/** Request the Google Play access token */ 
     private def getAccessToken(): Future[String] = { 

     ws.url("https://www.googleapis.com/oauth2/v4/token") 
      .withHeaders("Content-Type" -> "application/x-www-form-urlencoded") 
      .post(
      Map(
       "grant_type" -> Seq("urn:ietf:params:oauth:grant-type:jwt-bearer"), 
       "assertion" -> Seq(generateJWT())) 
     ).map { 
      response => 
      try { 
       (response.json \ "access_token").as[String] 
      } catch { 
       case ex: Exception => throw new IllegalArgumentException("GooglePlayAPI - Invalid response: ", ex) 
      } 
     } 

     } 

손에있는 액세스 토큰을 사용하면 구입 한 항목을 자유롭게 확인할 수 있습니다.

나는 희망한다.

+1

노력에 감사드립니다. 그러나이 질문은 거의 1 년 전임 – kwantuM

+2

맞습니다. 그러나 일주일 전에 필요했는데 어떤 확실한 답을 찾지 못했습니다. 그것은 다른 사람을 도울 수 있습니다;) –

1

위의 내 의견에 이어 Google API 관리자는 디자인이 변경되었지만 절차는 동일합니다. 서비스 계정을 만들고 싶다면 JSON 웹 토큰을 다운로드하면 인증 할 수있는 자격 증명이있는 간단한 JSON 파일입니다. 서비스 계정에는 Google Play 개발자 API에 액세스하는 데 필요한 모든 액세스 권한이 있어야합니다. Google Play 개발자 콘솔> 설정> API 액세스 페이지에서 금융에 대한 액세스 권한을 부여해야합니다.

Google APIs Client Library for Java을 사용하여 Google Play 개발자 API를 인증하고 요청할 수 있습니다. 설정을 위해 OAuth2 Service accounts 문서를 따르십시오. 새로 고침 토큰이 처리되는 방법을 설명하는 Data store에 대한 메모가 있습니다.

Google Play Developer API Client Library for Java을 사용하는 방법에 대한 문서도 있습니다.

구매 JSON의 서명을 확인하는 경우 구매 의도의 응답 페이로드에 INAPP_DATA_SIGNATURE이 있습니다. 가져 오는 방법에 대한 자세한 내용은 Purchasing an Item에있는 문서를 참조하십시오. INAPP_PURCHASE_DATA을 base64로 서명을 디코딩하고 Google Play 개발자 콘솔> 모든 애플리케이션> [앱 이름]> 서비스 & API에있는 라이센스 키로 확인하면 확인할 수 있습니다. INAPP_PURCHASE_DATA이 손상되지 않았 으면 this problem으로 끝납니다.

희망이 도움이됩니다.