0

고객 계정이 여러 개인 시스템이 있으며 각 계정에는 Google 웹 로그 분석 계정이있는 웹 사이트가 하나 이상 있습니다. 고객이 내 시스템에서 Google 웹 로그 분석 계정에 액세스 할 수 있도록 승인해야 월별 리포트 페이지 자동보기를 생성하고이 정보를 내 시스템의 다른 정보와 함께 제공 할 수 있습니다. 고객이 Google 웹 로그 분석 계정에 신청서를 다시 승인 할 필요없이이 작업을 수행하고 싶습니다.Ruby on Rails에서 Google OAuth2 API 사용

클라이언트가 Google 애널리틱스에 대한 액세스를 허용하면 약 1 시간 동안 실행됩니다 (세션 시간 토큰 expires_in: 3600으로 생각됩니다). 이 시간이 지나면 Google 웹 로그 분석 클라이언트에 액세스 할 수 없습니다. 코드에서 볼 수 있듯이 나는 이미 access_type:: offline을 사용하고 클라이언트 토큰을 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 
+0

사용자가 인증하면 사용자는 새로 고침을받을 수 있습니다. 계정에 액세스해야 할 때 새 액세스 토큰을 얻는 데 사용할 수있는 새로 고침 토큰을 저장해야합니다. – DaImTo

+0

이미 저장하고 있습니다. 새로 고침 토큰을 사용하여 새 액세스 토큰을 얻으려면 어떻게해야합니까? – maurymmarques

답변

0

은 간단했지만, 난 내 테스트에서 API를 호출에서 token_credential_uri를 넣어되지 않은 생각합니다.

"How do I refresh my google_oauth2 access token using my refresh token? "나는 올바른 방법을 찾았습니다.

방금 ​​API 호출에 다음 매개 변수를 추가했습니다. client_id, client_secret, token_credential_urirefresh_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