2012-04-17 16 views
8

Tengo una aplicación donde los usuarios pueden vincular sus cuentas de Facebook. Pueden iniciar sesión usando su correo electrónico, pero pueden vincular su cuenta de Facebook.Rails - Facebook con Omniauth y Koala: Cómo renovar un token caducado

En la vista en donde muestro las redes sociales vinculadas (Facebook y otros), que tienen algo como esto:

<%= image_tag @facebook.get_facebook_picture %> 

Para ello, será un método de instancia como esta:

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 

Este funcionará bien a menos que el token de Facebook que he almacenado en mi base de datos haya caducado. Así que he añadido este gestor de excepciones en el controlador mencionado:

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 

I detectar la excepción correctamente, pero no puedo ver cómo iba a renovar el token de acceso que tengo en mi base de datos. Tenga en cuenta que el token de acceso que tengo se ha insertado utilizando OmniAuth. Entonces mi pregunta es:

Dado que tengo un OAuthException, ¿cómo puedo renovar el token de acceso de un usuario en particular (UID) usando Omniauth?

+0

Dado que esto no es una respuesta a su pregunta, Voy a dejar un comentario ... pero usted debería ser capaz de agarrar el imágenes sin un token activo usando: 'profile_pic = Koala :: Facebook :: GraphAPI.new.get_picture (fb_uid, {: type =>" large "})', ¿no? – courtsimas

+0

Si desea obtener el token extendido de 60 días, [esto puede ayudar] (http://stackoverflow.com/a/16721737/805003) – manafire

Respuesta

9

El caso simple es que vuelve a autenticar al usuario con FB, exactamente como usted los autorizó en primer lugar. Para obtener la ficha en primer lugar, asumo que estás usando omniauth (y onmiauth-facebook) para autenticarte contra FB. Eso significa que tiene una ruta y una acción de controlador para manejar la devolución de llamada de autenticación, y una función que inserta el token en la base de datos.

El token de acceso que originalmente recibió con omniauth puede dejar de ser válido por varias razones: vencimiento, o porque el usuario cambió su contraseña de FB y posiblemente otras. En esos casos, otra llamada OAuth devolverá un token válido. Simplemente llame de nuevo (como lo hizo cuando autorizó por primera vez al usuario) y reemplace el token no válido con el nuevo, en su base de datos, y está listo.

This gist (my own answer a una pregunta relacionada que hice aquí) tiene un código que lo cubre, pero parece que ya lo tienes cubierto. Guarde suficiente estado para luego volver a intentar lo que sea que desencadenó la excepción y usted está bien.

También es posible que el token no sea válido porque el usuario ha cambiado la configuración de su aplicación FB para desautorizar su aplicación. En ese caso, el usuario verá el cuadro de diálogo de permisos de FB como si fuera un nuevo usuario que se autentica contra FB por primera vez. (FB)

¿Tiene sentido?

+0

Gracias por la respuesta. Mi pregunta es: ¿cómo actualizo el token directamente sin tener que mostrar la ventana de autenticación al usuario? – Nobita

+0

Mientras la aplicación todavía esté autorizada y el usuario aún esté conectado a FB, su llamada automática tendrá éxito de forma silenciosa.El usuario solo verá una ventana de autenticación si es necesario por alguna razón (están desconectados de FB, o han desautorizado su aplicación y necesitan volver a autorizarla). –

+0

No he dicho que el usuario haya iniciado sesión en absoluto ... Estoy usando Omniauth para permitir a los usuarios vincular sus cuentas a la aplicación (para publicarlas posteriormente en sus paredes) pero no como un método de registro. – Nobita

2

Puede cambiar la conexión tutorial Railscasts koala con esto:

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

Mis experimentos muestran que este enfoque en realidad no extiende el tiempo de caducidad, el token nuevo caducará al mismo tiempo que el anterior. – biomancer

+0

@biomancer Encontré eso también, ¿Hay alguna manera de renovar un token? –

+1

@NickGinanto Parece que no hay forma de hacerlo sin interactuar con el usuario. Terminé mostrando un aviso especial a los usuarios, que tienen sus tokens caducados, con un mismo enlace omniauth que se utiliza para iniciar sesión/registrarse. El usuario pasa por el flujo estándar de OAuth y yo recibo un nuevo token en mi devolución de llamada de Omniauth. – biomancer

Cuestiones relacionadas