22

我正在编写一个 Rails 应用程序,该应用程序使用omniauth-facebook 对FB 用户进行身份验证(并为用户获取FB OAuth 访问令牌)。然后,该应用程序使用 Koala 使用保存的 OAuth 令牌对 FB Graph API 进行各种调用。

每次用户重新进行身份验证时(通常在他们登录到我的应用程序时),我都会更新保存的令牌。即便如此,该保存的令牌仍会不时过期(或以其他方式变为无效)。

使用 Koala 时防止身份验证失败和更新令牌的最佳做法是什么?

是否应该将所有调用都包装在开始/救援块中,并使用异常处理程序重新验证用户对 FB 的身份?

有没有办法(使用考拉)利用这里描述的“扩展访问令牌”过程?如果没有,是否有编写自己的代码以自己从考拉调用中提取新令牌的最佳实践?

4

3 回答 3

17

我所拥有的是一个 before_filter,它在需要活动 Facebook 会话的每个页面上触发。像这样的东西应该工作:

  before_filter :reconnect_with_facebook
  def reconnect_with_facebook
    if current_account && current_account.token_expired?(session[:fb]["expires"])

    # re-request a token from facebook. Assume that we got a new token so
    # update it anyhow...
    session[:return_to] = request.env["REQUEST_URI"] unless request.env["REQUEST_URI"] == facebook_request_path
    redirect_to(with_canvas(facebook_request_path)) and return false
  end
end

token_expired?方法如下所示:

def token_expired?(new_time = nil)
  expiry = (new_time.nil? ? token_expires_at : Time.at(new_time))
  return true if expiry < Time.now ## expired token, so we should quickly return
  token_expires_at = expiry
  save if changed?
  false # token not expired. :D
end
于 2012-05-01T01:03:19.090 回答
17

我看到了这篇文章,它改编了 Facebook 上 Railscast 的代码,展示了如何将短期令牌换成 60 天的令牌:

用户.rb

 def self.from_omniauth(auth)

    # immediately get 60 day auth token
    oauth = Koala::Facebook::OAuth.new(ENV["FACEBOOK_APP_ID"], ENV["FACEBOOK_SECRET"])
    new_access_info = oauth.exchange_access_token_info auth.credentials.token

    new_access_token = new_access_info["access_token"]
    # Facebook updated expired attribute
    new_access_expires_at = DateTime.now + new_access_info["expires_in"].to_i.seconds

    where(auth.slice(:provider, :uid)).first_or_initialize.tap do |user|
      user.provider = auth.provider
      user.uid = auth.uid
      user.name = auth.info.name
      user.image = auth.info.image
      user.email = auth.info.email
      user.oauth_token = new_access_token #originally auth.credentials.token
      user.oauth_expires_at = new_access_expires_at #originally Time.at(auth.credentials.expires_at)
      user.save!
    end
  end
于 2013-05-23T18:54:01.787 回答
0

您可以执行类似的操作,检查 access_token 是否已过期并生成另一个。

 %w[facebook].each do |provider|
   scope provider, -> { where(provider: provider) }
 end

 def client
   send("#{provider}_client")
 end

 def expired?
   expires_at? && expires_at <= Time.zone.now
 end

 def access_token
   send("#{provider}_refresh_token!", super) if expired?
   super
 end

 def facebook_refresh_token!(token)
   new_token_info = 
   Koala::Facebook::OAuth.new.exchange_access_token_info(token)
   update(access_token: new_token_info["access_token"], expires_at: Time.zone.now + new_token_info["expires_in"])
 end

您可以查看gorails 截屏视频,该视频详细解释了这一点。

于 2017-12-04T17:25:35.587 回答