Implementieren von Discourse Apple Login über API

Hallo, ich arbeite daran, eine API für die Discourse-Anmeldung mit Apple zu erstellen. Ich habe das Plugin bereits installiert und die Anweisungen von Discourse Apple Authentication befolgt. Es funktioniert gut, wenn ich mich über ein Apple-Konto bei Discourse anmelde, wenn ich die Website benutze.

Nachdem ich den Ablauf der Apple-Anmeldung im Web überprüft hatte, bemerkte ich, dass er zur Apple-Seite für die Anmeldung weiterleitet, einen von Apple generierten Code nach erfolgreicher Anmeldung erhält und dann weiterleitet zu:

POST {{discourse_host}}/auth/apple/callback mit den Parametern state:{state}, code:{code from Apple}

Danach leitet er weiter zu GET {{discourse_host}}/auth/apple/callback?code={{code from Apple}}&state={state}, wodurch ein neuer Cookie generiert wird, der in der Discourse-API verwendet wird.

Aus diesem Ablauf erwarte ich, dass nach dem Aufruf von /auth/apple/callback ein neuer Cookie generiert wird.

Aber wenn ich versuche, die API aufzurufen, wird der Fehler Authorization timed out, or you have switched browsers. Please try again. angezeigt.

Also habe ich es erneut mit einem neuen von Apple generierten Code versucht, aber immer noch den gleichen Fehler erhalten.

Und wenn ich das Log überprüfe, wird angezeigt:

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

Ich möchte also fragen, ob diese Richtung zur Verwendung der Discourse-Apple-Anmeldung über API korrekt ist und wie ich das Problem mit dem csrf_detected-Fehler lösen kann.

Die Apple-Authentifizierung (und tatsächlich alle anderen Authentifizierungsmethoden in Discourse) sind nicht für die Verwendung über die API konzipiert. Sie sollten direkt von Endbenutzern in einem unterstützten Browser verwendet werden.

Welches Problem versuchen Sie hier zu lösen? Vielleicht können wir eine alternative Lösung finden?

1 „Gefällt mir“

Hallo @david, danke für deine Antwort. Was ich hier erreichen möchte, ist die Erstellung einer API für die Apple-Anmeldung, die von der mobilen App für den Zugriff auf die Discourse-API verwendet wird.

Für die Verwendung der Discourse-API zur Anmeldung mit E-Mail und Passwort funktioniert dies gut mit den folgenden beiden Discourse-APIs:

  1. {{discourse_host}}/session/csrf.json: Diese API gibt einen Cookie und einen CSRF-Code zurück, die für die Anmeldung mit der nächsten API verwendet werden.
  2. {{discourse_host}}/session: Diese API gibt einen neuen Cookie zurück, der für den Zugriff auf andere Discourse-APIs verwendet werden kann.
Csrf API

Session

Ich erwarte, dass es ähnlich wie bei der Apple-Anmeldung in Discourse ist, wo ich eine Anfrage an die Discourse-API stelle, um den _t-Cookie zu generieren.

Hallo @david, hast du eine Lösung für mein Problem?

Ich fürchte, es gibt keine einfache Antwort. Authentifizierungs-APIs wie diese sind speziell dafür konzipiert, zu vermeiden, dass sie ohne echte Benutzerinteraktion im Web ausgelöst werden.

Für Ihren Anwendungsfall wäre die gängigere Lösung die Verwendung des Benutzer-API-Schlüssel-Systems. Dies ermöglicht es Discourse, 100 % der Authentifizierungslogik zu handhaben und gibt Ihrer App pro Benutzer API-Schlüssel. Diese Strategie sollte wesentlich robuster sein, als zu versuchen, eine Benutzersitzung zu „fälschen“.

1 „Gefällt mir“