OmniAuth Facebook过期令牌错误

时间:2011-10-02 20:19:40

标签: ruby-on-rails ruby facebook rubygems omniauth

我正在使用OmniAuth在我的应用中访问Facebook。我正在使用fb_graph gem:https://github.com/nov/fb_graph发布到Facebook。我正在Heroku上为这个应用程序运行omniauth-0.3.0。创建用户时保存的令牌会在用户稍后登录时更改。

创建用户的代码

    class SessionsController < ApplicationController  
    def create  
     auth = request.env["omniauth.auth"]  
     user = User.find_by_provider_and_uid(auth["provider"], auth["uid"])||           
     User.create_with_omniauth(auth)
       session[:user_id] = user.id  
       redirect_to root_url, :notice => "Signed in!"  
         end 

用户模型是:

  def self.create_with_omniauth(auth)  
    create! do |user|  
    user.provider = auth["provider"]  
    user.uid = auth["uid"]  
    user.name = auth["user_info"]["name"] 
    user.token = auth["credentials"]["token"]
    end
   end

我现在在大约30%的用户身上看到了这个错误 -

 FbGraph::InvalidToken (OAuthException :: Error validating access token: Session does not match current stored session. This may be because the user changed the password since the time the session was created or Facebook has changed the session for security reasons.)

我看到过期的令牌问题最近已在OmniAuth中修复:

https://github.com/soopa/omniauth/commit/67bdea962e3b601b8ee70e21aedf5e6ce1c2b780

我使用此代码尝试刷新访问令牌。但是,我仍然得到同样的错误。有人能指出我所缺少的东西吗? 每次用户登录时,是否还有其他方式可以更新令牌?

唯一有效的解决方案是每次用户登录时创建一个新用户(我根本不喜欢这个解决方案):

  def create  
    auth = request.env["omniauth.auth"] 
    user = User.create_with_omniauth(auth)
    session[:user_id] = user.id  
    redirect_to root_url, :notice => "Signed in!"  
  end

谢谢!

3 个答案:

答案 0 :(得分:7)

您可以在创建会话时更新令牌。

class SessionsController < ApplicationController  
def create  
  auth = request.env["omniauth.auth"]  
  user = User.find_by_provider_and_uid(auth["provider"], auth["uid"]).tap do |u|
           u.update_attributes(:token => auth["credentials"]["token"]) if u
         end || User.create_with_omniauth(auth)
  session[:user_id] = user.id  
  redirect_to root_url, :notice => "Signed in!"  
end 

答案 1 :(得分:2)

在你回答这个问题之前,我使用的是类似的解决方案 -

  class SessionsController < ApplicationController  
  def create  
 auth = request.env["omniauth.auth"]  
 user = User.find_by_provider_and_uid(auth["provider"], auth["uid"]) ||  User.create_with_omniauth(auth)  

 user.update_attributes(:token => auth["credentials"]["token"])

 session[:user_id] = user.id  
 redirect_to root_url, :notice => "Signed in!"  

  end

答案 2 :(得分:1)

在这种情况下,我们是否可以使用FBGraph gem使用后续方法刷新令牌?

auth = FbGraph::Auth.new(CLIENT_ID, CLIENT_SECRET)
auth.exchange_token! access_token # Needs fb_graph 2.3.1+
auth.access_token # => new token

但是,这不会延长令牌的到期时间,但会用新的令牌替换令牌。到期时间将保持不变。用FB检查,他们可能不允许延长FB令牌到期超过60天。 最高令牌有效期为60天。

参考:https://github.com/nov/fb_graph/wiki/Authentication#wiki-extend-token-expiry