【问题标题】:Access Google Calendar API after setting up omniauth in rails在rails中设置omniauth后访问谷歌日历API
【发布时间】:2023-03-22 20:42:02
【问题描述】:

我有一个使用 gem 'omniauth-google-oauth2' 的 rails 应用程序。到目前为止一切正常。现在,我正在尝试在用户关联 Google 帐户后提取用户日历。

我已经遵循了几个教程,但似乎无法提取日历信息。使用的所有教程:

gem 'google-api-client', '~> 0.7.0', 要求:'google/api_client'

问题是,我已经尝试了这么久,我很困惑可能是什么问题。

在设置 Omniauth 后开始,如何在我的 rails 应用中提取 Google 日历信息?

【问题讨论】:

    标签: ruby-on-rails calendar google-calendar-api


    【解决方案1】:

    我一直在努力寻找使用google-api-client 版本0.9 的正确解决方案,我非常感谢遇到Sophie's blog post with Josh' 评论。以下是我如何使用他们的输入的快速回顾:

    require 'google/apis/calendar_v3'
    require 'google/api_client/client_secrets.rb'
    
    secrets = Google::APIClient::ClientSecrets.new(
      { "web" => 
        { "access_token" => "YOUR_ACCESS_TOKEN", 
          "refresh_token" => "YOUR_REFRESH_TOKEN", 
          "client_id" => "YOUR_CLIENT_ID", 
          "client_secret" => "YOUR_CLIENT_SECRET"
        }
      }
    )
    cal = Google::Apis::CalendarV3::CalendarService.new
    cal.authorization = secrets.to_authorization
    cal.authorization.refresh!
    
    data = cal.list_calendar_lists
    

    阅读 migration to 0.9 manual 以了解随着这个新 gem 版本的出现发生了怎样的变化,这也可能会有所帮助。

    【讨论】:

    • 我想知道,是否有必要检查refresh! 是否有必要?如果access_token 没有过期,这将为我们节省额外的 Google 之旅。
    • 是的;这当然是有道理的。但是我还没有找到办法,而且这已经运行了一年多,所以我坚持这样做。
    【解决方案2】:

    我终于让它工作了。

    我将 :google_access_token、:google_refresh_token 和 :google_expires_at 添加到我的用户模型中。并使用:

    @user.google_access_token  = request.env["omniauth.auth"]["credentials"]["token"]
    @user.google_refresh_token = request.env["omniauth.auth"]["credentials"]["refresh_token"]
    @user.google_expires_at    = Time.at request.env["omniauth.auth"]["credentials"]["expires_at"]
    @user.save
    

    在我的omniauth回调控制器中存储它并通过它来访问它。

    client = Google::APIClient.new(:auto_refresh_token => true)
    client.authorization.access_token = current_user.google_access_token
    client.authorization.refresh_token = current_user.google_refresh_token
    client.authorization.client_id = ENV.fetch('google_id')
    client.authorization.client_secret = ENV.fetch('google_secret')
    
    if client.authorization.refresh_token && client.authorization.expired?
      client.authorization.fetch_access_token!
    end
    
    service = client.discovered_api('calendar' , 'v3')
    
    response = client.execute(api_method: service.events.list,
            parameters: { 'calendarId' => 'primary' },
              headers: { 'Content-Type' => 'application/json' })
    
    @items = response.data['items']
    

    【讨论】:

    • Sebhastien,你能看看我的问题(共享为答案)吗?如果我以这种方式分享,我希望你不介意。我不想提出新问题,因为我的问题和你的完全一样。
    【解决方案3】:

    假设用户已授权您的应用程序,并且您已存储访问令牌和刷新令牌,并且访问令牌具有访问用户日历的范围。

    • 首先初始化客户端并获取新的access_token并指定你要使用的服务及其版本

      client=Google::APIClient.new(:auto_refresh_token => true)

      client.authorization.access_token = 令牌

      client.authorization.refresh_token = refresh_token

      client.authorization.client_id = client_id

      client.authorization.client_secret = client_secret

      token = client.authorization.fetch_access_token["access_token"]

      service = client.discovered_api('calendar' , 'v3')

    • 使用客户端对象调用任何 api 方法,这里我调用 'events.list' 从日历中获取用户事件

      response = client.execute(api_method: service.events.list, parameters: { 'calendarId' => 'primary' }, headers: { 'Content-Type' => 'application/json' })

    【讨论】:

    • 我认为这可能是这个问题的核心。我不确定我是否存储了访问令牌。我没有收到错误,而且我在谷歌开发者控制台中根本没有显示任何活动。我只看到登录活动。如何存储访问令牌和刷新令牌?
    • 假设您使用omniauth-google-oauth2 进行身份验证,您需要的所有信息都在身份验证成功后返回的身份验证哈希中,更多信息在这里github.com/zquestz/omniauth-google-oauth2#auth-hash。您可以按照本教程sourcey.com/…检查身份验证后的流程以存储访问令牌和刷新令牌,以及您向 api 发出的每个请求,然后您可以在答案中使用上述流程。
    • 是的,这与我用来配置 oauth 的教程相同。但是如何存储访问令牌和刷新令牌?您上面提供的代码似乎可以工作,但我现在收到“缺少访问令牌”错误。
    【解决方案4】:

    sby 能告诉我,Sebhastien 的解决方案和我的解决方案有什么区别吗? (我的代码还没有准备好,还不知道能否通过我的解决方案获得新的 access_token。)

    1.我只是不知道何时以及如何获得新的访问令牌,以及是否需要处理 refresh_token 和 expires_at 属性。

    2.(:auto_refresh_token => true)fetch_access_token! 究竟是如何工作的?

    client = Google::APIClient.new
    #next 4 lines get the data from app/db
    client.authorization.access_token = google_account.token
    client.authorization.client_id = ENV['GOOGLE_API_KEY']
    client.authorization.client_secret = ENV['GOOGLE_API_SECRET']
    client.authorization.refresh_token = google_account.refresh_token
    
    old_token = client.authorization.access_token
    service = client.discovered_api('calendar', 'v3')
    result = client.execute(
      :api_method => service.calendar_list.list,
      :parameters => {},
      :headers => {'Content-Type' => 'application/json'})
    
    new_token = client.authorization.access_token
    if old_token != new_token
      Social.update_attribute(token: new_token) #saving new token to db
    end
    
    @items = result.data['items']
    

    【讨论】:

      猜你喜欢
      • 2015-11-05
      • 1970-01-01
      • 2021-06-17
      • 2016-04-01
      • 1970-01-01
      • 2020-11-04
      • 1970-01-01
      • 1970-01-01
      • 2016-04-15
      相关资源
      最近更新 更多