2012-04-17 30 views
8

Mam aplikację, w której użytkownicy mogą łączyć swoje konta na Facebooku. Mogą logować się za pomocą poczty e-mail, ale mogą połączyć swoje konto na Facebooku.Szyny - Facebook z Omniauth i Koala: Jak odnowić wygasły token

W widoku gdzie mogę pokazać połączonych sieci społecznościowych (Facebook i inne), mam coś takiego:

<%= image_tag @facebook.get_facebook_picture %> 

To będzie wywołać metodę instancji tak:

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 

ten będzie działać dobrze, chyba że znacznik Facebooka, który zapisałem w mojej bazie danych, wygasł. Więc dodałem ten obsługi wyjątku we wspomnianym kontrolerze:

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 

złapię wyjątek poprawnie, ale nie widzę w jaki sposób odnowić token dostępu, który mam w bazie danych. Zauważ, że token dostępu, który mam, został wstawiony za pomocą OmniAuth. Więc moje pytanie brzmi:

Biorąc pod uwagę, że mam OAuthException, w jaki sposób mogę odnowić token dostępu określonego użytkownika (UID) przy użyciu Omniauth?

+0

Ponieważ to nie jest odpowiedź na pytanie, po prostu komentarza ... ale powinieneś być w stanie chwycić zdjęcia bez aktywnego tokena za pomocą: 'profile_pic = Koala :: Facebook :: GraphAPI.new.get_picture (fb_uid, {: type =>" large "})', prawda? – courtsimas

+0

Jeśli chcesz uzyskać przedłużony 60-dniowy żeton, [to może pomóc] (http://stackoverflow.com/a/16721737/805003) – manafire

Odpowiedz

9

Prostym przypadkiem jest ponowne uwierzytelnienie użytkownika za pomocą FB, dokładnie tak, jak je autoryzowałeś. Aby zdobyć token, zakładam, że używasz omniauth (i onmiauth-facebook) do uwierzytelniania się na FB. Oznacza to, że masz trasę i akcję kontrolera, aby obsłużyć wywołanie zwrotne auth oraz funkcję wstawiającą token do bazy danych.

Token dostępu, który pierwotnie otrzymałeś za pomocą omniauth, może stać się nieważny z różnych powodów - wygaśnięcia lub ponieważ użytkownik zmienił swoje hasło FB, a być może także inne. W takich przypadkach kolejne wywołanie OAuth zwróci ważny token. Po prostu zadzwoń ponownie (tak jak to zrobiłeś, gdy po raz pierwszy autoryzowałeś użytkownika) i zastąp nieważny token nowym, w twoim DB i jesteś dobry.

This gist (my own answer do pokrewnego pytania, o które pytałem) ma trochę kodu, ale to brzmi, jakby już to zostało omówione. Zapisz stan dostatecznie, aby następnie spróbować ponownie, niezależnie od tego, co spowodowało wyjątek i jesteś dobry.

Jest również możliwe, że token jest teraz nieważny, ponieważ użytkownik zmienił ustawienia aplikacji FB, aby cofnąć autoryzację aplikacji. W takim przypadku użytkownik zobaczy okno dialogowe uprawnień FB, tak jakby był nowym użytkownikiem uwierzytelniającym się na FB po raz pierwszy. (FB)

Czy to ma sens?

+0

Dzięki za odpowiedź. Moje pytanie brzmi: jak zaktualizować token bezpośrednio, bez konieczności pokazywania użytkownikowi okna auth? – Nobita

+0

Dopóki aplikacja jest nadal autoryzowana, a użytkownik jest nadal zalogowany do FB, połączenie oauth zakończy się sukcesem.Z jakiegoś powodu użytkownik zobaczy okno autoryzacji tylko wtedy, gdy będzie potrzebne (wylogowane z FB lub cofnęli autoryzację aplikacji i muszą ponownie ją autoryzować). –

+0

Nie powiedziałem, że użytkownik jest w ogóle zalogowany ... Używam Omniauth, aby umożliwić użytkownikom łączenie ich kont z aplikacją (w celu umieszczenia ich w ścianach), ale nie jako metodę rejestrowania. – Nobita

2

Można zmienić RailsCasts koala połączenia samouczka z tym:

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

Moje eksperymenty pokazują, że to podejście nie wydłuża czasu wygaśnięcia, nowy token wygaśnie w tym samym czasie, co stary. – biomancer

+0

@biomancer Znalazłem to również, Czy istnieje sposób na odnowienie tokena? –

+1

@NickGinanto Wygląda na to, że nie można tego zrobić bez interakcji z użytkownikiem. Skończyło się na tym, że dla użytkowników, którzy mają już swoje tokeny, wydano specjalne ostrzeżenie z tym samym linkiem omniauth, który służy do logowania/rejestracji. Użytkownik przechodzi przez standardowy przepływ OAuth i otrzymuję nowy token w wywołaniu zwrotnym Omniauth. – biomancer