ruby-on-rails - gema - rails devise google
Devise/OmniAuth anula la URL de devoluciĆ³n de llamada predeterminada (2)
Estoy usando Devise 3.5 con Omniauth en una aplicación de Rails 4. Creé una integración con Facebook que permite a un usuario conectar su cuenta de Facebook a mi aplicación. Actualmente, cuando el usuario hace clic en el botón de conexión, se envía a /user/auth/facebook
y luego se le redirige a la url de devolución de llamada que genera Omniauth: /user/auth/facebook/callback
. Lo que me gustaría hacer es anular manualmente esta url de devolución de llamada en algunos casos, lo que significa que no quiero anularla en un inicializador, con una url totalmente calificada . Por ejemplo, si un usuario comienza en http://www.example.com/
, es posible que desee sobrescribir la url de devolución de llamada predeterminada con http://app.example.com/user/auth/facebook/callback
.
Mi aplicación tiene subdominios dinámicos y un usuario (casi) siempre comenzará el proceso de autenticación en un subdominio. Desafortunadamente, parece que Facebook no admite comodines en las direcciones de redireccionamiento oauth, por lo que quiero la capacidad de detectar si un usuario está en un subdominio y ajustar la URL de devolución de llamada a algo que he incluido en mi aplicación de Facebook para que la autorización proceso tiene éxito
Por lo que he leído, el url helper omniauth_authorize_path
acepta argumentos adicionales para pasar como parámetros. Intenté pasar una ruta de devolución de llamada personalizada de esa manera, pero sin éxito:
user_omniauth_authorize_path(:facebook, callback_path: @custom_callback)
También intenté cambiar callback_path
por redirect_url
y redirect_uri
, pero parece que nada funciona. Cuando miro el enlace que se genera, sí incluye la devolución de llamada como un parámetro en la url, pero cuando hago clic en el vínculo, me redirigen a la url de devolución de llamada predeterminada en lugar de a la url de devolución de llamada personalizada.
¿Has probado con redirect_uri?
user_omniauth_authorize_path(:facebook, redirect_uri: @custom_callback)
EDIT: lamento haberme perdido la segunda parte de tu publicación.
De hecho, tengo el mismo problema en producción pero funciona perfectamente en un entorno de ensayo. La única diferencia es sobre la url de devolución de llamada en la etapa que tiene un subdominio más * .staging.domain.com
Por cierto, puede proporcionar un callback_url estático en el archivo de inicializador del proyecto:
config.oaumniauth :facebook, ..., callback_url: ''url right here''
Estoy en este tema esto ayer. O bien proporciono una url de devolución de llamada estática, pero facebook me plantea un error de CRSF:
omniauth: (facebook) Authentication failure! csrf_detected: OmniAuth::Strategies::OAuth2::CallbackError, csrf_detected | CSRF detected
O dejo que el dispositivo configure callback_url dinámicamente, que se verá como
https://*.domain.com/DEVISE_MODELS/auth/facebook
y en este caso, recibo una url de devolución de llamada directa no coincidente / lista blanca durante el proceso de inicio de sesión de FG.
EDIT2:
¡BUENO! Lo hice. Puedo iniciar sesión con Oauth con el subdominio comodín.
- Proporcione un callback_url estático en su inicializador de diseño
- agregue el dominio a su tienda de sesión como: dominio: ".dominio.com"
Con eso no recibo ni error CRSF ni nunmatching CB url / whitelisted.
Espero que funcione para ti!
Así es como resolví este problema. Estoy seguro de que hay otras formas, pero esta parece ser la solución más elegante y sencilla que pude encontrar.
En config/routes.rb
configuré un subdominio de auth
. Todas mis solicitudes de conexión de Oauth se iniciarán en diferentes subdominios y luego Facebook se configura para reenviar esos usuarios al subdominio auth.example.com
.
constraints AuthRedirect do
devise_scope :contact do
get ''/auth/facebook/callback'' => ''omniauth_callbacks#facebook''
post ''/auth/facebook/callback'' => ''omniauth_callbacks#facebook''
end
end
Aquí está /lib/auth_redirect.rb
. Esto solo comprueba si el subdominio es auth
y captura ese tráfico. Esto se coloca en la parte superior de la lista de rutas para que tenga prioridad sobre otros subdominios.
class AuthRedirect
def self.matches?(request)
request.subdomain.present? && request.subdomain == ''auth''
end
end
Luego, en mi cliente, cuando un usuario hace clic en el botón Connect with Facebook
, los envío a /auth/facebook?contact_id=<id>
. Desde aquí, Devise los dirige a Facebook, que luego los redirige a https://auth.example.com/
.
Luego, en OmniauthCallbacksController#facebook
, puedo extraer la identificación del usuario de los parámetros de omniauth así:
auth = env["omniauth.auth"]
contact = Contact.find(env[''omniauth.params''][''contact_id''])
Desde aquí, puedo conservar las credenciales en la base de datos y redirigir al usuario al subdominio apropiado. Esta solución evita problemas con tokens CSRF y, lo que es más importante, no requiere que use Ruby / ERB para compilar la ruta de autorización de omniauth a la que se envía al usuario cuando hace clic en el botón de conexión.