繁体   English   中英

结合使用Google OAuth2 API和Ruby on Rails

[英]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_idclient_secrettoken_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

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM