[英]Using Google OAuth2 API with Ruby on Rails
我的系統有多個客戶帳戶,每個帳戶至少有一個擁有Google Analytics(分析)帳戶的網站。 我需要我的客戶授權我的系統訪問Google Analytics(分析)帳戶,這樣我才能生成每月的自動報表瀏覽量,並向他們展示此信息以及系統的其他信息。 我想這樣做,而無需客戶再次將我的應用程序授權給他們的Google Analytics(分析)帳戶。
當客戶端授權訪問Google Analytics(分析)時,它將運行大約1個小時(我認為這是會話時間令牌expires_in: 3600
)。 此后,我將無法訪問Google Analytics(分析)客戶端。 如您在代碼中看到的,我已經嘗試過使用access_type:: offline
並使用client.update_token!
更新客戶端令牌client.update_token!
但我不知道該怎么做。 誰能告訴我我想做的事情是否可行,並告訴我如何做,以便我可以生成月度報告,而無需客戶再次授權我的應用程序?
我在控制器中創建了一些方法(我知道代碼不好,這只是一個測試,也許我應該在將訪問令牌寫入數據庫之前對其進行加密)。
class ContractedProductsController < ApplicationController
def analytics_connection
client_info = {
client_id: Rails.configuration.x.google_api['client_id'],
client_secret: Rails.configuration.x.google_api['client_secret'],
authorization_uri: Rails.configuration.x.google_api['authorization_uri'],
scope: Google::Apis::AnalyticsV3::AUTH_ANALYTICS_READONLY,
redirect_uri: url_for(action: :analytics_callback),
state: Base64.encode64('{ "account": ' + params[:account_id] + ', "contracted_product": ' + params[:id] + ' }'),
additional_parameters: { access_type: :offline, approval_prompt: :force }
}
client = Signet::OAuth2::Client.new(client_info)
redirect_to client.authorization_uri.to_s
end
def analytics_callback
client_info = {
client_id: Rails.configuration.x.google_api['client_id'],
client_secret: Rails.configuration.x.google_api['client_secret'],
token_credential_uri: Rails.configuration.x.google_api['token_credential_uri'],
redirect_uri: url_for(action: :analytics_callback),
code: params[:code]
}
client = Signet::OAuth2::Client.new(client_info)
response = client.fetch_access_token!
session[:google_api] = response
state = JSON.parse(Base64.decode64(params[:state]), object_class: OpenStruct)
redirect_to account_contracted_product_analytics_list_path(state.account, state.contracted_product)
end
def analytics_list
client = Signet::OAuth2::Client.new(access_token: session[:google_api]['access_token'])
service = Google::Apis::AnalyticsV3::AnalyticsService.new
service.authorization = client
@account_summaries = service.list_account_summaries
end
def analytics_save
api_integrations = [
{
entity_type: ContractedProduct.name,
entity_id: @contracted_product.id,
key: ApiIntegration::GOOGLE_ANALYTICS_KEYS[:access_token],
value: session[:google_api]['access_token']
},
{
entity_type: ContractedProduct.name,
entity_id: @contracted_product.id,
key: ApiIntegration::GOOGLE_ANALYTICS_KEYS[:refresh_token],
value: session[:google_api]['refresh_token']
},
{
entity_type: ContractedProduct.name,
entity_id: @contracted_product.id,
key: ApiIntegration::GOOGLE_ANALYTICS_KEYS[:profile_id],
value: params[:profile_id]
}
]
@api_integration = ApiIntegration.create(api_integrations)
respond_to do |format|
if @api_integration
format.html { redirect_to [@account, @contracted_product], notice: I18n.t('controllers.contracted_products.analytics_data_successfully_saved', default: 'Analytics data was successfully saved.') }
format.json { render :show, status: :ok, location: [@account, @contracted_product] }
else
format.html { render :analytics_save, status: :ok, location: [@account, @contracted_product] }
format.json { render json: @contracted_products_service.errors, status: :unprocessable_entity }
end
end
end
def analytics_report
entity_conditions = { entity_type: ContractedProduct.name, entity_id: @contracted_product.id }
api_integration_access_token = ApiIntegration.find_by entity_conditions.merge(key: ApiIntegration::GOOGLE_ANALYTICS_KEYS[:access_token])
# api_integration_refresh_token = ApiIntegration.find_by entity_conditions.merge(key: ApiIntegration::GOOGLE_ANALYTICS_KEYS[:refresh_token])
api_integration_profile_id = ApiIntegration.find_by entity_conditions.merge(key: ApiIntegration::GOOGLE_ANALYTICS_KEYS[:profile_id])
client = Signet::OAuth2::Client.new(access_token: api_integration_access_token.value)
service = Google::Apis::AnalyticsV3::AnalyticsService.new
service.authorization = client
profile_id = 'ga:' + api_integration_profile_id.value
start_date = Date.today.at_beginning_of_month.last_month.to_s
end_date = Date.today.at_beginning_of_month.last_month.to_s
metrics = 'ga:pageviews'
dimensions = {
dimensions: 'ga:date'
}
@report = service.get_ga_data(profile_id, start_date, end_date, metrics, dimensions)
end
end
那很容易,但是我想我並沒有在測試中對API的調用中放入token_credential_uri
。
觀察到此答案“ 如何使用刷新令牌刷新google_oauth2訪問令牌? ”我找到了正確的方法。
我剛剛在API調用中添加了以下參數: client_id
, client_secret
, token_credential_uri
和refresh_token
。
def analytics_report
entity_conditions = { entity_type: ContractedProduct.name, entity_id: @contracted_product.id }
api_integration_refresh_token = ApiIntegration.find_by entity_conditions.merge(key: ApiIntegration::GOOGLE_ANALYTICS_KEYS[:refresh_token])
api_integration_profile_id = ApiIntegration.find_by entity_conditions.merge(key: ApiIntegration::GOOGLE_ANALYTICS_KEYS[:profile_id])
client_info = {
client_id: Rails.configuration.x.google_api['client_id'],
client_secret: Rails.configuration.x.google_api['client_secret'],
token_credential_uri: Rails.configuration.x.google_api['token_credential_uri'],
refresh_token: api_integration_refresh_token.value
}
client = Signet::OAuth2::Client.new(client_info)
service = Google::Apis::AnalyticsV3::AnalyticsService.new
service.authorization = client
profile_id = 'ga:' + api_integration_profile_id.value
start_date = Date.today.at_beginning_of_month.last_month.to_s
end_date = Date.today.at_beginning_of_month.last_month.to_s
metrics = 'ga:pageviews'
dimensions = {
dimensions: 'ga:date'
}
@report = service.get_ga_data(profile_id, start_date, end_date, metrics, dimensions)
end
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.