在服务器端验证应用内购买Android / Google

时间:2013-08-14 11:19:23

标签: ruby oauth-2.0 in-app-purchase google-play google-play-services

我想在Android应用中使用应用内购买的购买令牌来验证我自己服务器上的google服务器。

使用以下代码我可以验证令牌,但每次都必须使用我的OAuth凭据验证自己:

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

有没有人知道如何在服务器上没有像OAuth这样的东西来验证服务器?还有另一种认证可能吗?

谢谢!

1 个答案:

答案 0 :(得分: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