2012-04-17 23 views
8

我有一個應用程序,用戶可以鏈接他們的Facebook帳戶。他們可以使用他們的電子郵件登錄,但他們可以鏈接他們的Facebook帳戶。Rails - Facebook的Omniauth和考拉:如何更新過期的代幣

在我展示鏈接的社交網絡(Facebook和其他人)的觀點,我有這樣的事情:

<%= image_tag @facebook.get_facebook_picture %> 

這將調用一個實例方法是這樣的:

def get_facebook_picture 
    unless self.token.nil? 
     facebook_graph = Koala::Facebook::GraphAPI.new(self.token) 
     fb_picture = facebook_graph.get_picture("me", { :type => "small" }) 
    end 
end 

這將工作得很好,除非我存儲在我的數據庫中的Facebook標記已過期。所以,我在提到控制器添加了這個異常處理程序:

def facebook_exception_handler exception 
    if exception.fb_error_type.eql? 'OAuthException' 
     # Let's get a new auth token... How? 
    else 
     logger.debug "Damn it. We don't know what error is coming from FB" 
     raise exception 
    end 
end 

我正確地捕捉到了異常,但我看不出我怎麼會續約,我有我的數據庫中訪問令牌。請注意,我擁有的訪問令牌已經使用OmniAuth插入。所以我的問題是:

鑑於我有一個OAuthException,如何使用Omniauth更新特定用戶(UID)的訪問令牌?

+0

因爲這不是一個回答你的問題,我就發表評論......但你應該能夠搶沒有使用活動標記的圖片:'profile_pic = Koala :: Facebook :: GraphAPI.new.get_picture(fb_uid,{:type =>「large」})',對吧? – courtsimas 2012-05-08 18:52:54

+0

如果你想得到擴展的60天令牌,[這可能有幫助](http://stackoverflow.com/a/16721737/805003) – manafire 2013-05-23 19:06:22

回答

9

簡單的情況是,您使用FB重新授權用戶,就像您首先授權他們一樣。爲了獲得令牌,我假設你正在使用omniauth(和onmiauth-facebook)對FB進行身份驗證。這意味着你有一個路由和一個控制器動作來處理auth回調,以及一個將令牌插入到db中的函數。

您最初使用omniauth獲取的訪問令牌可能由於各種原因而失效 - 失效,或者因爲用戶更改了他們的FB密碼以及其他可能的原因。在這些情況下,另一個OAuth調用將返回一個有效的令牌。再次調用(就像你第一次授權用戶時所做的那樣),並用數據庫中的新代碼替換無效令牌,而且你很好。

This gistmy own answer到一個相關的問題,我問這裏)有一些代碼覆蓋,但它聽起來像你已經得到了覆蓋。保存足夠的狀態,然後重新嘗試觸發異常的任何事情,而且你很好。

此標記現在也可能無效,因爲用戶已更改其FB應用設置以取消您的應用授權。在這種情況下,用戶將看到FB權限對話框,就好像他們是第一次使用FB進行身份驗證的新用戶一樣。 (FB

這有道理嗎?

+0

感謝您的答案。我的問題是:如何直接更新令牌而不必向用戶顯示授權窗口? – Nobita 2012-04-17 06:31:18

+0

只要應用程序仍被授權並且用戶仍然登錄到FB,您的oauth調用將會靜默地成功。如果需要出於某種原因,用戶將只能看到一個授權窗口(他們從FB中註銷,或者他們已經取消授權應用程序並需要重新授權)。 – 2012-04-17 06:36:52

+0

我沒有說用戶登錄了...我使用的是Omniauth讓用戶將他們的帳戶鏈接到應用程序(用於後發佈到他們的牆上),但不是作爲日誌記錄方法。 – Nobita 2012-04-17 06:39:46

2

你可以用這個RailsCasts考拉教程連接:

def facebook 
    if self.facebook_expires_at < Time.now 
    oauth = Koala::Facebook::OAuth.new(ENV["FACEBOOK_KEY"], ENV["FACEBOOK_SECRET"]) 
    new_access_info = oauth.exchange_access_token_info self.facebook_token 

    new_access_token = new_access_info["access_token"] 
    new_access_expires_at = DateTime.now + new_access_info["expires"].to_i.seconds 

    self.update_attributes!(:facebook_token => new_access_token, 
          :facebook_expires_at => new_access_expires_at) 
    end 
    @facebook ||= Koala::Facebook::API.new(self.facebook_token) 
    block_given? ? yield(@facebook) : @facebook 

    rescue Koala::Facebook::APIError => e 
    logger.info e.to_s 
    nil 
end 
+1

我的實驗表明,這種方法實際上不會延長到期時間,新的令牌將與舊的令牌同時過期。 – biomancer 2014-07-30 13:31:05

+0

@biomancer我也發現,有沒有辦法更新令牌? – 2015-02-08 11:48:06

+1

@NickGinanto它看起來像沒有辦法做到這一點沒有與用戶交互。我最終向用戶發出了特別通知,他們的令牌已過期,並且有一個用於登錄/註冊的omniauth鏈接。用戶通過標準的OAuth流程,並在我的Omniauth回調中收到新的令牌。 – biomancer 2015-02-08 12:16:43

相關問題