Implementar login Apple do Discourse usando API

Olá, estou trabalhando na criação de uma API para login no Discourse usando Apple. Já instalei o plugin e segui as instruções de Autenticação Apple do Discourse. Funciona bem ao fazer login no Discourse usando uma conta Apple no site.

Ao verificar o fluxo de login da Apple pela web, notei que ele redireciona para a página da Apple para login, obtém um código gerado pela Apple após o login bem-sucedido e, em seguida, redireciona para:

POST {{discourse_host}}/auth/apple/callback com os parâmetros state:{state}, code:{code from Apple}

Depois disso, ele redireciona para GET {{discourse_host}}/auth/apple/callback?code={{code from Apple}}&state={state}, gerando um novo cookie que será usado na API do Discourse.

A partir deste fluxo, espero que ele gere um novo cookie após a chamada /auth/apple/callback.

Mas quando tento chamar a API, ele mostra o erro Authorization timed out, or you have switched browsers. Please try again.

Então, tentei novamente com um novo código gerado pela Apple, mas ainda obtive o mesmo erro.

E quando verifico o log, ele 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!'

Então, quero perguntar se essa direção para usar o login da Apple do Discourse via API está correta e como posso resolver o problema com o erro csrf_detected.

A autenticação da Apple (e, de fato, todos os outros métodos de autenticação no Discourse) não foi projetada para ser usada via API. Eles devem ser usados diretamente por usuários finais em um navegador compatível.

Qual problema você está tentando resolver aqui? Talvez possamos encontrar uma solução alternativa?

1 curtida

Olá @david, obrigado pela sua resposta. O que eu quero alcançar aqui é criar uma API para login com a Apple que será usada pelo aplicativo móvel para acessar a API do Discourse.

Para usar a API do Discourse para fazer login com e-mail e senha, funciona bem usando estas duas APIs do Discourse:

  1. {{discourse_host}}/session/csrf.json: Esta API retorna um cookie e um código CSRF, que serão usados para login usando a próxima API.
  2. {{discourse_host}}/session: Esta API retorna um novo cookie que pode ser usado para acessar outras APIs do Discourse.
API Csrf

Sessão

Espero que seja semelhante ao login com a Apple no Discourse, onde eu faço uma solicitação à API do Discourse para gerar o cookie _t.

Olá @david, você tem uma solução para o meu problema?

Receio que não haja uma resposta fácil. APIs de autenticação como esta são projetadas especificamente para evitar que sejam acionadas sem interação real do usuário na web.

Para o seu caso de uso, a solução mais comum seria usar o sistema de chaves de API de usuário. Isso permitirá que o Discourse lide com 100% da lógica de autenticação e fornecerá ao seu aplicativo chaves de API por usuário. Essa estratégia deve ser muito mais robusta do que tentar “fingir” uma sessão de usuário.

1 curtida