2011-10-02 3 views
3

Я использую OmniAuth для доступа к Facebook в своем приложении. Я использую fb_graph gem: https://github.com/nov/fb_graph для публикации в Facebook. Я запускаю omniauth-0.3.0 на Heroku для этого приложения. Токен, который я сохраняю при создании пользователя, изменяется, когда пользователь регистрируется через некоторое время.OmniAuth Facebook expired token error

код для создания пользователя

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

Я видел, что проблема с истекшим токеном была недавно исправлена ​​в 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 

Спасибо!

ответ

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

Благодарим за ответ. У меня был один вопрос - я использую логин FB, используя omniauth. Ток FB изменяется время от времени, поэтому токен может меняться, когда пользователь использует приложение после входа в систему. Чтобы это произошло, прямо сейчас я использую разрешение «offline_access», чтобы FB генерировал долгоживущие токены. Есть ли способ решить эту проблему без «offline_access». Возможно, мне понадобится мое приложение, чтобы просить обновленный токен через omniauth перед отправкой в ​​Facebook (в любое время после входа в систему). Есть ли другой способ решить эту проблему? –

+0

По моему опыту, единственный раз, когда токен изменился с помощью набора «offline_access», это когда пользователь меняет свой пароль на Facebook. Помимо этого, токены остались неизменными более года. Когда пароль меняется, им необходимо снова войти в систему, чтобы получить новый токен, как указано выше. – Brad

+0

Я согласен с тем, что вы говорите. Если параметр «offline_access» установлен, токен не изменился. Тем не менее, мне было интересно, как я могу справиться с этим без установки «offline_access»?(«offline_access» является дополнительным разрешением от пользователя, поэтому может возникнуть некоторое трение у некоторых пользователей, которым может не понравиться приложение «Доступ к их данным в любое время») –

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 
1

Мы не можем обновить маркер, используя FBGraph драгоценный камень с follwing метод в таком случае?

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