Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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

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!

like image 326
Shantanu Bhalerao Avatar asked Dec 12 '25 15:12

Shantanu Bhalerao


1 Answers

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 
like image 83
Brad Avatar answered Dec 14 '25 06:12

Brad