Facebook令牌到期和续约,与考拉和omniauth-facebook
我正在编写一个Rails应用程序,它使用omniauth-facebook来针对FB对用户进行身份validation(以及为用户获取FB OAuth访问令牌)。 然后,应用程序使用Koala使用保存的OAuth令牌对FB Graph API进行各种调用。
每次用户重新进行身份validation时(通常在他们登录我的应用程序时),我都会更新已保存的令牌。 即便如此,保存的令牌也会不时到期(或以其他方式变为无效)。
在使用Koala时,防止auth失败和更新令牌的最佳做法是什么?
是否应将所有调用包装在begin / rescue块中,并使用exception处理程序对FB重新validation用户?
是否有某种方式(使用Koala)来利用此处描述的“扩展访问令牌”流程? 如果没有,是否有编写自己的代码以从Koala调用中自己提取新令牌的最佳实践?
我所拥有的是在每个需要活动的Facebook会话的页面上触发的before_filter。 像这样的东西应该工作:
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
我发现这篇文章改编了Facebook上Railscast的代码,以展示如何为60天的代码交换短期代币:
user.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
您可以执行以下操作,检查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截屏video ,深入解释这一点。
- 请求的资源上不存在“Access-Control-Allow-Origin”标头
- 使用Omniauth和Rails 3在Facebook登录时在Web和触摸界面之间切换
- 链接在身份validation和聚合数据中
- 在rails应用程序中使用OmniAuth时,为什么我总是遇到Errno :: ETIMEDOUT
- 仅使用omniauth(twitter)登录与Devise,Rails 3,Omniauth
- Omniauth-facebook登录无法正常工作
- 从youtube登录OAuth保存用户的性别和位置
- 获取(omniauth-facebook)和(omniauth-twitter)工作
- 如何使用Minitest测试OmniAuth的SessionsController