Implementar inicio de sesión de Apple usando la API en Discourse

Hola, estoy trabajando en la creación de una API para el inicio de sesión de Discourse usando Apple. Ya he instalado el plugin y seguido las instrucciones de Autenticación de Apple en Discourse. Funciona bien al iniciar sesión en Discourse usando una cuenta de Apple en el sitio web.

Al revisar el flujo de inicio de sesión de Apple desde la web, noté que redirige a la página de Apple para iniciar sesión, obtiene un código generado por Apple tras un inicio de sesión exitoso y luego redirige a:

POST {{discourse_host}}/auth/apple/callback con los parámetros state:{state}, code:{code from Apple}

Después de eso, redirige a GET {{discourse_host}}/auth/apple/callback?code={{code from Apple}}&state={state}, generando una nueva cookie que se utilizará en la API de Discourse.

A partir de este flujo, espero que genere una nueva cookie después de la llamada a /auth/apple/callback.

Pero cuando intento llamar a la API, muestra el error Authorization timed out, or you have switched browsers. Please try again.

Así que lo intenté de nuevo con un nuevo código generado por Apple, pero todavía obtuve el mismo error.

Y cuando reviso el registro, muestra:

Started GET "/auth/apple/callback?code=c32f105b5084d42b8bd3e7051873ddb55.0.rrzxz.pChPU9zGlXIHHhgEXLiA5g&state=fbi3bbboud" for
(apple) Setup endpoint detected, running now.
(apple) Callback phase initiated.
(apple) Authentication failure! csrf_detected: OmniAuth::Strategies::OAuth2::CallbackError, csrf_detected | CSRF detected
Started GET "/auth/failure?message=csrf_detected&strategy=apple" for 123.253.233.16 at 2023-11-27 06:10:28 +0000
Processing by Users::OmniauthCallbacksController#failure as HTML
  Parameters: {"message"=>"csrf_detected", "strategy"=>"apple"}
  Rendered users/omniauth_callbacks/failure.html.erb within layouts/no_ember (Duration: 4.1ms | Allocations: 17)
  Rendered layout layouts/no_ember.html.erb (Duration: 57.5ms | Allocations: 2882)

Message (47 copies reported)

(apple) Authentication failure! csrf_detected: OmniAuth::Strategies::OAuth2::CallbackError, csrf_detected | CSRF detected

Backtrace

/var/www/discourse/vendor/bundle/ruby/3.2.0/gems/omniauth-1.9.2/lib/omniauth/strategy.rb:163:in `log'
/var/www/discourse/vendor/bundle/ruby/3.2.0/gems/omniauth-1.9.2/lib/omniauth/strategy.rb:486:in `fail!'
/var/www/discourse/vendor/bundle/ruby/3.2.0/gems/omniauth-oauth2-1.7.3/lib/omniauth/strategies/oauth2.rb:87:in `callback_phase'
/var/www/discourse/plugins/discourse-apple-auth/lib/omniauth_apple.rb:60:in `callback_phase'
/var/www/discourse/vendor/bundle/ruby/3.2.0/gems/omniauth-1.9.2/lib/omniauth/strategy.rb:238:in `callback_call'
/var/www/discourse/vendor/bundle/ruby/3.2.0/gems/omniauth-1.9.2/lib/omniauth/strategy.rb:189:in `call!'
/var/www/discourse/vendor/bundle/ruby/3.2.0/gems/omniauth-1.9.2/lib/omniauth/strategy.rb:169:in `call'
/var/www/discourse/vendor/bundle/ruby/3.2.0/gems/omniauth-1.9.2/lib/omniauth/strategy.rb:192:in `call!'
/var/www/discourse/vendor/bundle/ruby/3.2.0/gems/omniauth-1.9.2/lib/omniauth/strategy.rb:169:in `call'
/var/www/discourse/vendor/bundle/ruby/3.2.0/gems/omniauth-1.9.2/lib/omniauth/strategy.rb:192:in `call!'

Así que quiero preguntar si esta dirección para usar el inicio de sesión de Apple de Discourse usando la API es correcta y cómo resuelvo el problema con el error csrf_detected.

La autenticación de Apple (y, de hecho, todos los demás métodos de autenticación en Discourse) no están diseñados para ser utilizados a través de la API. Deben ser utilizados directamente por los usuarios finales en un navegador compatible.

¿Qué problema intentas resolver aquí? Quizás podamos encontrar una solución alternativa.

1 me gusta

Hola @david, gracias por tu respuesta. Lo que quiero lograr aquí es crear una API para el inicio de sesión de Apple que será utilizada por la aplicación móvil para acceder a la API de Discourse.

Para usar la API de Discourse para iniciar sesión con correo electrónico y contraseña, funciona bien usando estas dos APIs de Discourse:

  1. {{discourse_host}}/session/csrf.json: Esta API devuelve una cookie y un código CSRF, que se utilizarán para iniciar sesión utilizando la siguiente API.
  2. {{discourse_host}}/session: Esta API devuelve una nueva cookie que se puede utilizar para acceder a otras APIs de Discourse.
API Csrf

Sesión

Espero que sea similar al inicio de sesión de Apple en Discourse, donde hago una solicitud a la API de Discourse para generar la cookie _t.

Hola @david, ¿tienes una solución para mi problema?

Me temo que no hay una respuesta fácil. Las API de autenticación como esta están diseñadas específicamente para evitar que se activen sin la interacción real del usuario en la web.

Para tu caso de uso, la solución más común sería utilizar el sistema de claves API de usuario. Esto permitirá a Discourse manejar el 100% de la lógica de autenticación y le dará a tu aplicación claves API por usuario. Esa estrategia debería ser mucho más robusta que intentar “simular” una sesión de usuario.

1 me gusta