Implementare login Apple tramite API

Ciao, sto lavorando alla creazione di un’API per l’accesso a Discourse utilizzando Apple. Ho già installato il plugin e seguito le istruzioni di Discourse Apple Authentication. Funziona bene quando si accede a Discourse utilizzando un account Apple sul sito web.

Dopo aver controllato il flusso di accesso di Apple dal web, ho notato che reindirizza alla pagina di Apple per l’accesso, ottiene un codice generato da Apple al termine dell’accesso e quindi reindirizza a:

POST {{discourse_host}}/auth/apple/callback con parametri state:{state}, code:{code from Apple}

Dopo di che, reindirizza a GET {{discourse_host}}/auth/apple/callback?code={{code from Apple}}&state={state}, generando un nuovo cookie che verrà utilizzato nell’API di Discourse.

Da questo flusso mi aspetto che venga generato un nuovo cookie dopo la chiamata a /auth/apple/callback

Ma quando provo a chiamare l’API, viene visualizzato l’errore Authorization timed out, or you have switched browsers. Please try again.

Quindi ho riprovato con un nuovo codice generato da Apple, ma ho ancora lo stesso errore.

E quando controllo il log, mostra:

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!'

Quindi vorrei chiedere se questa direzione per utilizzare l’accesso Apple di Discourse tramite API è corretta e come posso risolvere il problema con l’errore csrf_detected.

L’autenticazione Apple (e, di fatto, tutti gli altri metodi di autenticazione in Discourse) non sono progettati per essere utilizzati tramite API. Dovrebbero essere utilizzati direttamente dagli utenti finali in un browser supportato.

Quale problema stai cercando di risolvere? Forse possiamo trovare una soluzione alternativa?

1 Mi Piace

Ciao @david, grazie per la tua risposta. Quello che voglio ottenere qui è creare un’API per l’accesso ad Apple che verrà utilizzata dall’app mobile per accedere all’API di Discourse.

Per utilizzare l’API di Discourse per accedere con email e password, funziona bene utilizzando queste due API di Discourse:

  1. {{discourse_host}}/session/csrf.json: Questa API restituisce un cookie e un codice CSRF, che verranno utilizzati per l’accesso utilizzando la prossima API.
  2. {{discourse_host}}/session: Questa API restituisce un nuovo cookie che può essere utilizzato per accedere ad altre API di Discourse.
API Csrf

Sessione

Mi aspetto che sia simile all’accesso Apple in Discourse, dove faccio una richiesta all’API di Discourse per generare il cookie _t.

Ciao @david, hai una soluzione per il mio problema?

Temo che non ci sia una risposta facile. Le API di autenticazione come questa sono specificamente progettate per evitare che vengano attivate senza una reale interazione dell’utente sul web.

Per il tuo caso d’uso, la soluzione più comune sarebbe utilizzare il sistema user API keys. Ciò consentirà a Discourse di gestire il 100% della logica di autenticazione e fornirà alla tua app alcune chiavi API per utente. Questa strategia dovrebbe essere molto più robusta rispetto al tentativo di “falsificare” una sessione utente.

1 Mi Piace