4

I would like to use the purchase token from the in app purchases in an android app to validate it to the google server on my own server.

With the following code I can validate a token, but I have to authenticate myself with my OAuth credentials every time:

class GooglePlayVerification
  require 'google/api_client'

  # Refer:
  # https://code.google.com/p/google-api-ruby-client/issues/detail?id=72
  # and
  # http://jonathanotto.com/blog/google_oauth2_api_quick_tutorial.html
  # and
  # http://milancermak.wordpress.com/2012/08/24/server-side-verification-of-google-play-subsc/
  GOOGLE_KEY = 'xxx.apps.googleusercontent.com'
  GOOGLE_SECRET = 'xxxx'
  APP_NAME = 'xx.xx.xx'
  SCOPE = "https://www.googleapis.com/auth/androidpublisher"

  def self.token
    @@token ||= begin
      require 'oauth2'
      raise "Missing client_id variable" if GOOGLE_KEY.to_s.empty?
      raise "Missing client_secret variable" if GOOGLE_SECRET.to_s.empty?
      raise "Missing scope variable" if SCOPE.to_s.empty?

      redirect_uri = 'https://localhost/oauth2callback'

      auth_client_obj = OAuth2::Client.new(GOOGLE_KEY, GOOGLE_SECRET, {:site => 'https://accounts.google.com', :authorize_url => "/o/oauth2/auth", :token_url => "/o/oauth2/token"})

      puts "1) Paste this URL into your browser where you are logged in to the relevant Google account\n\n"
      puts auth_client_obj.auth_code.authorize_url(:scope => SCOPE, :access_type => "offline", :redirect_uri => redirect_uri, :approval_prompt => 'force')

      puts "\n\n\n2) Accept the authorization request from Google in your browser:"

      puts "\n\n\n3) Google will redirect you to localhost, but just copy the code parameter out of the URL they redirect you to, paste it here and hit enter:\n"
      code = gets.chomp.strip

      access_token_obj = auth_client_obj.auth_code.get_token(code, {:redirect_uri => redirect_uri, :token_method => :post})
      puts "Result: #{access_token_obj.inspect}\n\n"
      puts "Token is: #{access_token_obj.token}"
      puts "Refresh token is: #{access_token_obj.refresh_token}"

      {
          :access_token => access_token_obj.token,
          :refresh_token => access_token_obj.refresh_token,
          :expires_in => access_token_obj.expires_in,
          :expires_at => access_token_obj.expires_at
      }
    end
  end

  def self.refresh_token
    refresh_client_obj = OAuth2::Client.new(GOOGLE_KEY, GOOGLE_SECRET, {:site => 'https://accounts.google.com', :authorize_url => '/o/oauth2/auth', :token_url => '/o/oauth2/token'})
    refresh_access_token_obj = OAuth2::AccessToken.new(refresh_client_obj, token[:access_token], {refresh_token: token[:refresh_token]})
    refresh_access_token_obj.refresh!
    puts "refresh token: #{refresh_access_token_obj.inspect}"
    @@token = {
        :access_token => refresh_access_token_obj.token,
        :refresh_token => refresh_access_token_obj.refresh_token,
        :expires_in => refresh_access_token_obj.expires_in,
        :expires_at => refresh_access_token_obj.expires_at
    }
  end


  # ie. https://developers.google.com/android-publisher/v1/
  # eg.
  # @subscription_id com.stocklight.stocklight.standardsubscription
  # @purchase_token  xxx
  def self.verify_subscription(subscription_id, purchase_token)
    response = RestClient.get "https://www.googleapis.com/androidpublisher/v1.1/applications/#{APP_NAME}/inapp/#{subscription_id}/purchases/#{purchase_token}?access_token=#{token[:access_token]}"
    puts "Respnse \n #{response.inspect}"
    puts response.code == 200
    puts JSON.parse(response)

    return response.code == 200 && JSON.parse(response)['kind'] =='androidpublisher#inappPurchase'
  rescue
    return false
  end

end

Has anyone an idea how to authenticate a server without such things like OAuth on the server? Is there another authentification possibility?

Thanks!

4

1 回答 1

2

这是我的红宝石代码:

def self.verify_subscription(subscription_id, transaction_id)
    json = JSON.parse(transaction_id)
    order = ["orderId", "packageName", "productId", "purchaseTime", "purchaseState", "purchaseToken"]
    signature = json["signature"]
    data = {}
    order.each do |o|
      data[o] = json[o]
    end
    key = OpenSSL::PKey::RSA.new(Base64.decode64(GOOGLE_PUBLIC_KEY))
    verified = key.verify(OpenSSL::Digest::SHA1.new, Base64.decode64(signature), data.to_json)
    verified
end
于 2013-10-11T08:20:57.473 回答