Pregunta

Estoy usando la gema OmniAuth con rieles y funciona muy bien con loging de usuarios, pero cada vez que le lleva a la página de inicio de sesión fb entonces vuelve a dirigir hacia atrás. Me preguntaba si hay una manera de hacer lo que la mayoría de las páginas hacen y mostrar la entrada FB en una ventana emergente y vuelva a cargar el div padre una vez finalizado. Algunas ideas?

Gracias!

¿Fue útil?

Solución

Claro, usted puede fácilmente.

En su opinión:

=link_to "Log in with Facebook", omniauth_authorize_path(:user, :facebook), :class => "popup", :"data-width" => 600, :"data-height" => 400

En sus application.js:

function popupCenter(url, width, height, name) {
  var left = (screen.width/2)-(width/2);
  var top = (screen.height/2)-(height/2);
  return window.open(url, name, "menubar=no,toolbar=no,status=no,width="+width+",height="+height+",toolbar=no,left="+left+",top="+top);
}

$("a.popup").click(function(e) {
  popupCenter($(this).attr("href"), $(this).attr("data-width"), $(this).attr("data-height"), "authPopup");
  e.stopPropagation(); return false;
});

Y a continuación, en su opinión devolución de llamada:

:javascript
  if(window.opener) {
    window.opener.location.reload(true);
    window.close()
  }

Esto hará estallar su autenticación de Facebook en un centrado 600x400 emergente, a continuación, cuando el usuario vuelve a partir de la autenticación, la vista se cerrará la ventana emergente y actualizar la página principal. Se degrada con gracia si un usuario ctrl-clic en el enlace, o no tiene Javascript habilitado, también.

Otros consejos

Ok, así que hay un problema con solución de Chris Heald si está utilizando OmniAuth conjuntamente con Diseñar . El problema es que cuando vuelva a cargar la ventana (que se encuentra en la página de inicio de sesión), idearán le llevará a la root_path, ignorando por completo la url que estaba tratando de acceso y producirá el mensaje de error "Ya has iniciado sesión en". Esto tiene sentido porque Diseñar protege a un usuario conectado el acceso a la página de inicio de sesión mediante la reorientación de la página. Por volver a cargar la página de inicio de sesión inmediatamente después de iniciar la sesión, que va a terminar con este problema.

Así que mi solución para alguien que use Diseñar es la siguiente:

# add this wherever needed in your_authentications_or_callbacks_controller.rb
sign_in user
@after_sign_in_url = after_sign_in_path_for(user)
render 'callback', :layout => false

Así que normalmente, después de encontrar o crear un usuario utilizando el hash devuelto por un determinado proveedor (Facebook, Twitter, etc ..), que nosotros llamamos la función sign_in_and_redirect inventar. Pero no podemos redirigir el momento (recuerda, en este momento, el usuario se encuentra actualmente en una ventana emergente) así que simplemente sign_in el usuario.

El siguiente, tenemos que pasar a la URL que el usuario está tratando de acceder a la vista, y podemos conseguir que la URL utilizando el método del Legado after_sign_in_path_for.

Por último, tenemos que hacer la vista. Ya que sólo usaremos el fin de llamar algo de JavaScript, no hay necesidad de hacer el diseño, así que apagar para no retrasarnos. Aquí está ese punto de vista:

# views/your_authentications_or_callbacks/callback.html.erb
<script type="text/javascript">
  window.opener.location = '<%= @after_sign_in_url %>';
  window.close();
</script>

Se muestra esta manera, el usuario es redirigido a la URL correcta después de iniciar sesión y el mensaje de flash correcta.

con JavaScript desactivado

Después de algunas pruebas me di cuenta que esta solución no estaba permitiendo la autenticación sin JavaScript así que me gustaría hacer una adición.

function popupCenter(linkUrl, width, height, name) {
    var separator = (linkUrl.indexOf('?') !== -1) ? '&' : '?',
        url = linkUrl + separator + 'popup=true',
        left = (screen.width - width) / 2,
        top = (screen.height - height) / 2,
        windowFeatures = 'menubar=no,toolbar=no,status=no,width=' + width +
            ',height=' + height + ',left=' + left + ',top=' + top;
    return window.open(url, name, windowFeatures);
}

El cambio aquí es la adición de un parámetro simple llamado popup a la URL usando JavaScript. OmniAuth será tan amable de almacenar cualquier Parámetros de consulta añadido a la solicitud de URL. Así que, finalmente, comprobamos para ese parámetro en el controlador. Si es que existe, es porque JavaScript está habilitado:

if request.env['omniauth.params']['popup']
  render 'callback', :layout => false
else
  redirect_to @after_sign_in_url
end

Además, no se olvide de hacer lo mismo para su acción failure, que se llama cuando el usuario no acepta iniciar sesión.

No podría haber hecho esto sin solución de Chris Heald, por lo .. Muchas gracias!

Publicar en caso de que ayuda a los demás. Estaba usando la respuesta de Chris Heald, pero tuvo problemas con el bit final de Javascript a cerrar nuevos enlaces de la ventana. Por ejemplo, si he publicado un enlace a mi sitio en Facebook, cuando los usuarios hace clic en el enlace de la nueva ventana cerraba automáticamente en Chrome porque la condición sólo comprueba "si (window.opener)"

Terminé resolver esto con el uso de una variable global (popupValue). Puede haber soluciones más elegantes, pero pensé en compartir, en caso de que otros golpear el mismo problema:

function popupCenter(url, width, height, name) {
 var left = (screen.width/2)-(width/2);
 var top = (screen.height/2)-(height/2);
 popupValue = "on";
 return window.open(url, name, "menubar=no,toolbar=no,status=no,width="+width+",height="+height+",toolbar=no,left="+left+",top="+top     );
}

$(document).ready(function(){
$("a.popup").click(function(e) {
popupCenter($(this).attr("href"), $(this).attr("data-width"), $(this).attr("data-height"), "authPopup");
e.stopPropagation(); return false;
});


if(window.opener && window.opener.popupValue === 'on') {
 delete window.opener.popupValue;
 window.opener.location.reload(true);
 window.close()
}
});

terminé usando JS SDK de Facebook, ya que es más fácil.

# In facebook.js.coffee
jQuery ->
  $('body').prepend('<div id="fb-root"></div>')

  $.ajax
    url: "#{window.location.protocol}//connect.facebook.net/en_US/all.js"
    dataType: 'script'
    cache: true

window.fbAsyncInit = ->
  FB.init(appId: 'YOUR-APP-ID', cookie: true)

  $('#sign_in').click (e) ->
    e.preventDefault()
    FB.login (response) ->
      window.location = '/auth/facebook/callback' if response.authResponse

  $('#sign_out').click (e) ->
    FB.getLoginStatus (response) ->
      FB.logout() if response.authResponse
    true

Luego, en sus puntos de vista:

<%= link_to "Sign in with Facebook", "/auth/facebook", id: "sign_in" %>
<%= link_to "Sign out", signout_path, id: "sign_out" %>

Esto es directamente desde la punta de Sergio Gutiérrez aquí - https://coderwall.com/p/bsfitw

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top