开发者

OmniAuth Facebook expired token error

I am using OmniAuth to get access to Facebook in my app. I am using the fb_graph gem: https://github.com/nov/fb_graph to post to Facebook. I am running omniauth-0.3.0 on Heroku for this app. The token that I save when the user is created is changed when the user logs in sometime later.

Code for creating user

    class SessionsC开发者_开发技巧ontroller < 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 

The User model is:

  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

I am now seeing this error on about 30% users-

 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.)

I saw that the expired token issue has been recently fixed in OmniAuth:

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

I used this code which tries to refresh the access token. However, I still get the same error. Can someone point to what I am missing? Is there some other way I could update the token every time the user logs in?

The only solution which has worked is to create a new User everytime the User logs in (I don't like this solution at all):

  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

Thanks!


You can simply update the token when you create the session.

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 


I was using similar solution before you answered this question-

  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


Can't we refresh the token using FBGraph gem with follwing method in such case?

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

However, This will not extend token's expiry but will replace token with new one. Expiry time will remain same. Checked it with FB, They may not allow to extend FB token expiry more than 60 days. Maximum token validity is 60-days.

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

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜