2012-04-17 6 views
8

Ho un'applicazione in cui gli utenti possono collegare i loro account Facebook. Possono accedere utilizzando la loro e-mail, ma possono collegare il proprio account Facebook.Rails - Facebook con Omniauth e Koala: Come rinnovare un token scaduto

Nella vista in cui mostro le collegate social network (Facebook e altri), ho qualcosa di simile:

<%= image_tag @facebook.get_facebook_picture %> 

Questa chiamerà un metodo di istanza in questo modo:

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 

Questo funzionerà bene a meno che il token di Facebook che ho memorizzato nel mio DB sia scaduto. Così ho aggiunto questo gestore di eccezioni nel controller citato:

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 

ho intercettare l'eccezione correttamente, ma non riesco a vedere come avrei rinnovare il token di accesso che ho nel mio database. Si noti che il token di accesso che ho è stato inserito utilizzando OmniAuth. Quindi la mia domanda è:

Dato che ho un OAuthException, come posso rinnovare il token di accesso di un determinato utente (UID) usando Omniauth?

+0

Dal momento che questa non è una risposta alla tua domanda, mi limiterò a lasciare un commento ... ma si dovrebbe essere in grado di afferrare il immagini senza un token attivo usando: 'profile_pic = Koala :: Facebook :: GraphAPI.new.get_picture (fb_uid, {: type =>" large "})', giusto? – courtsimas

+0

Se si desidera ottenere il token esteso di 60 giorni, [questo potrebbe essere d'aiuto] (http://stackoverflow.com/a/16721737/805003) – manafire

risposta

9

Il caso semplice è che si re-autorizza l'utente con FB, esattamente come li ha autorizzati in primo luogo. Per ottenere il token in primo luogo, presumo che tu stia usando omniauth (e onmiauth-facebook) per autenticare contro FB. Ciò significa che hai un percorso e un'azione del controller per gestire il callback auth e una funzione che inserisce il token nel db.

Il token di accesso originariamente acquistato con omniauth può diventare non valido per vari motivi: scadenza o perché l'utente ha modificato la propria password FB e probabilmente altre. In questi casi, un'altra chiamata OAuth restituirà un token valido. Basta chiamare di nuovo (come hai fatto quando hai autorizzato per la prima volta l'utente) e sostituire il token non valido con quello nuovo, nel tuo DB, e sei a posto.

This gist (my own answer per una domanda correlata che ho chiesto qui) ha un codice che lo copre, ma sembra che tu abbia già ottenuto questo argomento. Salva lo stato sufficiente per poi riprovare ciò che ha attivato l'eccezione e sei a posto.

È inoltre possibile che il token non sia più valido perché l'utente ha modificato le impostazioni dell'app FB per rimuovere la propria app. In tal caso, l'utente vedrà la finestra di dialogo delle autorizzazioni FB come se fosse un nuovo utente che si autentica da FB per la prima volta. (FB)

Ha senso?

+0

Grazie per la risposta. La mia domanda è: come aggiorno il token direttamente senza dover mostrare la finestra auth all'utente? – Nobita

+0

Fintanto che l'app è ancora autorizzata e l'utente è ancora connesso a FB, la tua chiamata oauth avrà esito negativo.L'utente vedrà solo una finestra di autenticazione, se necessario, per qualche motivo (sono stati disconnessi da FB o hanno de-autorizzato la tua app e devono essere nuovamente autorizzati). –

+0

Non ho detto che l'utente ha effettuato l'accesso a tutti ... Sto utilizzando Omniauth per consentire agli utenti di collegare i loro account all'app (per la pubblicazione posteriore nei loro muri) ma non come metodo di registrazione. – Nobita

2

È possibile modificare la connessione esercitazione Railscasts koala con questo:

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

I miei esperimenti mostrano che questo approccio non prolunga in realtà il tempo di scadenza, il nuovo token scadrà contemporaneamente a quello vecchio. – biomancer

+0

@biomancer Ho scoperto anche che c'è un modo per rinnovare un token? –

+1

@NickGinanto Sembra che non ci sia modo di farlo senza interagire con l'utente. Ho finito per mostrare un avviso speciale agli utenti, che hanno i loro token scaduti, con lo stesso link omniauth utilizzato per l'accesso/registrazione. L'utente passa attraverso il flusso OAuth standard e ricevo un nuovo token nel mio callback Omniauth. – biomancer

Problemi correlati