Entrar com Apple

@David, o autor do PR respondeu ao meu comentário, qual é a sua opinião sobre isso?:

Eu:

Este PR parece resolver o problema da falta de nome e e-mail?

Autor do PR:

Não, infelizmente não. A Apple precisa fornecer um endpoint de API REST para recuperar nome/e-mail, pois atualmente eles só passam essas informações após uma autenticação bem-sucedida e não nas autenticações subsequentes.

Não seria suficiente para nós receber isso apenas uma vez na autorização inicial?

É melhor do que nada, mas ainda não é bom. Por exemplo, se você “fazer login com a Apple”, mas depois cancelar na tela de “criar conta”. Ou se conectar uma conta existente com a Apple e, em seguida, decidir criar uma nova conta. Esperemos que a Apple resolva isso antes do fim do beta :crossed_fingers:

5 curtidas

Existe alguma implementação funcional do recurso ‘Entrar com Apple’ nesta etapa? Um site para o qual estou trabalhando em um marketplace planeja ter um aplicativo iOS; no entanto, sem essa opção, não podemos habilitar outras opções de autenticação, a menos que queiramos que nosso aplicativo seja rejeitado por violar as diretrizes da loja de aplicativos.

Não que eu saiba. Estamos aguardando que esse problema seja resolvido: How to retrieve email and name? · Issue #8 · nhosoya/omniauth-apple · GitHub, embora o dono do repositório o tenha fechado de forma pouco útil.

Não tenho muita certeza, mas commits como este e os outros commits de agosto não resolvem o problema?

Sinta-se à vontade para instalar o plugin para testar, mas não tenho conhecimento de que isso já tenha sido resolvido. No entanto, não recomendo usá-lo em produção até que esteja concluído ou, pelo menos, aprovado por um desenvolvedor com tempo para confirmar os detalhes.

Sou um grande defensor desse recurso. Adoraria vê-lo integrado ao Discourse puro, como as outras opções de login.

Acho que é impossível recuperar esse tipo de informação de propósito.
:Exibir um botão de “Entrar com Apple” no seu aplicativo ou site significa que as pessoas podem entrar ou se cadastrar com apenas um toque, usando o ID da Apple que já possuem, sem precisar preencher formulários, verificar endereços de e-mail ou escolher senhas. O “Entrar com Apple” oferece uma nova e mais privada forma de acessar aplicativos e sites de forma simples e rápida, proporcionando uma experiência de login consistente e confiável, além da conveniência de não precisar lembrar de várias contas e senhas. Em casos em que você opta por solicitar nome e endereço de e-mail, as pessoas têm a opção de manter seu e-mail privado e compartilhar um endereço de e-mail único e aleatório em vez disso.

Veja o artigo completo para desenvolvedores da Apple

Você tem razão, a privacidade é uma das partes principais do ‘Entrar com Apple’, mas a parte fundamental da sua citação é:

Supondo que as pessoas escolham fornecer nome/e-mail, esperaríamos recebê-los do provedor a cada login do usuário. Na implementação atual, isso não acontece. Após a primeira autenticação, não recebemos mais nenhuma informação do usuário.

Não acho que isso seja algo que o autor do gem possa corrigir — é algo que a Apple precisaria alterar. Não vejo isso acontecendo anytime soon, então talvez precisemos apenas pedir aos usuários que insiram manualmente seu nome e e-mail no Discourse :cry:

4 curtidas

Sim, mas e as pessoas que acabam escolhendo não fornecer suas informações?

Ah, e aqui está um conceito rudimentar. :sweat_smile:

Boas notícias:

Consegui fazer funcionar parcialmente um fork do plugin de Robert/merefield (o fork envolve apenas a troca para uma cópia da gem omniauth que compilei a partir da fonte mais recente no GitHub). No entanto, no meu Discourse de teste (que possui HTTPS de ponta a ponta via ngrok), tive que definir a Configuração do Site “Cookies do site” para (nenhum) para que a autenticação funcionasse. Com a configuração desativada, consigo criar uma conta (mesmo se fechar o formulário de cadastro) e fazer login novamente; porém, não consigo fazê-lo se a configuração estiver ativada.

O backtrace de uma tentativa de login falha está abaixo:

Backtrace de login falho
/var/www/discourse/vendor/bundle/ruby/2.6.0/gems/logster-2.5.1/lib/logster/logger.rb:112:in `report_to_store'
/var/www/discourse/vendor/bundle/ruby/2.6.0/gems/logster-2.5.1/lib/logster/logger.rb:103:in `add_with_opts'
/var/www/discourse/vendor/bundle/ruby/2.6.0/gems/logster-2.5.1/lib/logster/logger.rb:54:in `add'
/usr/local/lib/ruby/2.6.0/logger.rb:543:in `error'
/var/www/discourse/vendor/bundle/ruby/2.6.0/gems/omniauth-1.9.0/lib/omniauth/strategy.rb:163:in `log'
/var/www/discourse/vendor/bundle/ruby/2.6.0/gems/omniauth-1.9.0/lib/omniauth/strategy.rb:486:in `fail!'
/var/www/discourse/vendor/bundle/ruby/2.6.0/gems/omniauth-oauth2-1.6.0/lib/omniauth/strategies/oauth2.rb:71:in `callback_phase'
/var/www/discourse/vendor/bundle/ruby/2.6.0/gems/omniauth-1.9.0/lib/omniauth/strategy.rb:238:in `callback_call'
/var/www/discourse/vendor/bundle/ruby/2.6.0/gems/omniauth-1.9.0/lib/omniauth/strategy.rb:189:in `call!'
/var/www/discourse/vendor/bundle/ruby/2.6.0/gems/omniauth-1.9.0/lib/omniauth/strategy.rb:169:in `call'
/var/www/discourse/vendor/bundle/ruby/2.6.0/gems/omniauth-1.9.0/lib/omniauth/strategy.rb:192:in `call!'
/var/www/discourse/vendor/bundle/ruby/2.6.0/gems/omniauth-1.9.0/lib/omniauth/strategy.rb:169:in `call'
/var/www/discourse/vendor/bundle/ruby/2.6.0/gems/omniauth-1.9.0/lib/omniauth/strategy.rb:192:in `call!'
/var/www/discourse/vendor/bundle/ruby/2.6.0/gems/omniauth-1.9.0/lib/omniauth/strategy.rb:169:in `call'
/var/www/discourse/vendor/bundle/ruby/2.6.0/gems/omniauth-1.9.0/lib/omniauth/strategy.rb:192:in `call!'
/var/www/discourse/vendor/bundle/ruby/2.6.0/gems/omniauth-1.9.0/lib/omniauth/strategy.rb:169:in `call'
/var/www/discourse/vendor/bundle/ruby/2.6.0/gems/omniauth-1.9.0/lib/omniauth/strategy.rb:192:in `call!'
/var/www/discourse/vendor/bundle/ruby/2.6.0/gems/omniauth-1.9.0/lib/omniauth/strategy.rb:169:in `call'
/var/www/discourse/vendor/bundle/ruby/2.6.0/gems/omniauth-1.9.0/lib/omniauth/strategy.rb:192:in `call!'
/var/www/discourse/vendor/bundle/ruby/2.6.0/gems/omniauth-1.9.0/lib/omniauth/strategy.rb:169:in `call'
/var/www/discourse/vendor/bundle/ruby/2.6.0/gems/omniauth-1.9.0/lib/omniauth/strategy.rb:192:in `call!'
/var/www/discourse/vendor/bundle/ruby/2.6.0/gems/omniauth-1.9.0/lib/omniauth/strategy.rb:169:in `call'
/var/www/discourse/vendor/bundle/ruby/2.6.0/gems/omniauth-1.9.0/lib/omniauth/builder.rb:64:in `call'
/var/www/discourse/lib/middleware/omniauth_bypass_middleware.rb:47:in `call'
/var/www/discourse/vendor/bundle/ruby/2.6.0/gems/rack-2.0.8/lib/rack/tempfile_reaper.rb:15:in `call'
/var/www/discourse/vendor/bundle/ruby/2.6.0/gems/rack-2.0.8/lib/rack/conditional_get.rb:38:in `call'
/var/www/discourse/vendor/bundle/ruby/2.6.0/gems/rack-2.0.8/lib/rack/head.rb:12:in `call'
/var/www/discourse/lib/content_security_policy/middleware.rb:12:in `call'
/var/www/discourse/lib/middleware/anonymous_cache.rb:318:in `call'
/var/www/discourse/vendor/bundle/ruby/2.6.0/gems/rack-2.0.8/lib/rack/session/abstract/id.rb:259:in `context'
/var/www/discourse/vendor/bundle/ruby/2.6.0/gems/rack-2.0.8/lib/rack/session/abstract/id.rb:253:in `call'
/var/www/discourse/vendor/bundle/ruby/2.6.0/gems/actionpack-6.0.1/lib/action_dispatch/middleware/cookies.rb:648:in `call'
/var/www/discourse/vendor/bundle/ruby/2.6.0/gems/actionpack-6.0.1/lib/action_dispatch/middleware/callbacks.rb:27:in `block in call'
/var/www/discourse/vendor/bundle/ruby/2.6.0/gems/activesupport-6.0.1/lib/active_support/callbacks.rb:101:in `run_callbacks'
/var/www/discourse/vendor/bundle/ruby/2.6.0/gems/actionpack-6.0.1/lib/action_dispatch/middleware/callbacks.rb:26:in `call'
/var/www/discourse/vendor/bundle/ruby/2.6.0/gems/actionpack-6.0.1/lib/action_dispatch/middleware/actionable_exceptions.rb:17:in `call'
/var/www/discourse/vendor/bundle/ruby/2.6.0/gems/actionpack-6.0.1/lib/action_dispatch/middleware/debug_exceptions.rb:32:in `call'
/var/www/discourse/vendor/bundle/ruby/2.6.0/gems/actionpack-6.0.1/lib/action_dispatch/middleware/show_exceptions.rb:33:in `call'
/var/www/discourse/vendor/bundle/ruby/2.6.0/gems/logster-2.5.1/lib/logster/middleware/reporter.rb:43:in `call'
/var/www/discourse/vendor/bundle/ruby/2.6.0/gems/railties-6.0.1/lib/rails/rack/logger.rb:38:in `call_app'
/var/www/discourse/vendor/bundle/ruby/2.6.0/gems/railties-6.0.1/lib/rails/rack/logger.rb:28:in `call'
/var/www/discourse/config/initializers/100-quiet_logger.rb:18:in `call'
/var/www/discourse/config/initializers/100-silence_logger.rb:31:in `call'
/var/www/discourse/vendor/bundle/ruby/2.6.0/gems/actionpack-6.0.1/lib/action_dispatch/middleware/remote_ip.rb:81:in `call'
/var/www/discourse/vendor/bundle/ruby/2.6.0/gems/actionpack-6.0.1/lib/action_dispatch/middleware/request_id.rb:27:in `call'
/var/www/discourse/lib/middleware/enforce_hostname.rb:17:in `call'
/var/www/discourse/vendor/bundle/ruby/2.6.0/gems/rack-2.0.8/lib/rack/method_override.rb:22:in `call'
/var/www/discourse/vendor/bundle/ruby/2.6.0/gems/actionpack-6.0.1/lib/action_dispatch/middleware/executor.rb:14:in `call'
/var/www/discourse/vendor/bundle/ruby/2.6.0/gems/rack-2.0.8/lib/rack/sendfile.rb:111:in `call'
/var/www/discourse/vendor/bundle/ruby/2.6.0/gems/actionpack-6.0.1/lib/action_dispatch/middleware/host_authorization.rb:77:in `call'
/var/www/discourse/vendor/bundle/ruby/2.6.0/gems/rack-mini-profiler-1.1.4/lib/mini_profiler/profiler.rb:184:in `call'
/var/www/discourse/vendor/bundle/ruby/2.6.0/gems/message_bus-2.2.3/lib/message_bus/rack/middleware.rb:57:in `call'
/var/www/discourse/lib/middleware/request_tracker.rb:181:in `call'
/var/www/discourse/vendor/bundle/ruby/2.6.0/gems/railties-6.0.1/lib/rails/engine.rb:526:in `call'
/var/www/discourse/vendor/bundle/ruby/2.6.0/gems/railties-6.0.1/lib/rails/railtie.rb:190:in `public_send'
/var/www/discourse/vendor/bundle/ruby/2.6.0/gems/railties-6.0.1/lib/rails/railtie.rb:190:in `method_missing'
/var/www/discourse/vendor/bundle/ruby/2.6.0/gems/rack-2.0.8/lib/rack/urlmap.rb:68:in `block in call'
/var/www/discourse/vendor/bundle/ruby/2.6.0/gems/rack-2.0.8/lib/rack/urlmap.rb:53:in `each'
/var/www/discourse/vendor/bundle/ruby/2.6.0/gems/rack-2.0.8/lib/rack/urlmap.rb:53:in `call'
/var/www/discourse/vendor/bundle/ruby/2.6.0/gems/unicorn-5.5.2/lib/unicorn/http_server.rb:605:in `process_client'
/var/www/discourse/vendor/bundle/ruby/2.6.0/gems/unicorn-5.5.2/lib/unicorn/http_server.rb:700:in `worker_loop'
/var/www/discourse/vendor/bundle/ruby/2.6.0/gems/unicorn-5.5.2/lib/unicorn/http_server.rb:548:in `spawn_missing_workers'
/var/www/discourse/vendor/bundle/ruby/2.6.0/gems/unicorn-5.5.2/lib/unicorn/http_server.rb:144:in `start'
/var/www/discourse/vendor/bundle/ruby/2.6.0/gems/unicorn-5.5.2/bin/unicorn:128:in `<top (required)>'
/var/www/discourse/vendor/bundle/ruby/2.6.0/bin/unicorn:23:in `load'
/var/www/discourse/vendor/bundle/ruby/2.6.0/bin/unicorn:23:in `<main>'

Alguém aqui tem sugestões sobre como ou se posso reescrever o plugin para que ele não precise mais desativar essa Configuração do Site para que suas funções principais funcionem? Meu código do plugin está em https://github.com/sau226dev/discourse-sign-in-with-apple e o código mais recente que usei para reconstruir a gem omniauth deve estar na mesma organização do GitHub.

Obrigado por qualquer ajuda que possam fornecer antecipadamente,

sau226

4 curtidas

O plugin originalmente funcionava até certo ponto, mas não tem recebido atenção recentemente devido ao problema descrito por David acima.

Até recebermos notícias positivas de que a Apple resolveu esse bloqueio fundamental (o envio de nome e e-mail em toda tentativa de login), não vale a pena manter esse código, na minha opinião. Não acredito que haja algo que você possa fazer para contornar isso. É por isso que nem mesmo tentei atualizar as dependências. De qualquer forma, o plugin falharia nos testes.

Portanto, este não é um plugin “lançado” (caso contrário, este ou um tópico similar estaria em #plugin) e é improvável que receba qualquer suporte até que isso aconteça. Eu ficaria muito feliz em “dar o acabamento final” se esse problema fosse resolvido e a Apple fornecesse essas informações.

Há também outra questão significativa, a propósito: para usá-lo em seu próprio site, é necessário pagar pelo Programa de Desenvolvedor da Apple para obter acesso à configuração nos sistemas da Apple. Isso deve afastar muitos sites com orçamento limitado, suspeito, já que não é uma inscrição gratuita ou de baixo custo.

6 curtidas

Acredito que @sau226 pareça sugerir que a falta de e-mail/nome retornados não é, de fato, um bloqueio?

@orenwolf Isso (a falta de e-mail/nome retornados em logins subsequentes) não parecia ser um problema. Acredito que consegui fechar a janela de cadastro e retomar o processo com os detalhes corretos passados. Como já mencionei, consegui fazer login com a Apple imediatamente depois, sem nenhum problema.

O único problema que enfrentei foi o erro CSRF, a menos que a configuração do site que mencionei acima fosse desativada. Um problema potencial é a ausência de um campo para nome no formulário de login e o fato de o nome de usuário ser tudo que vem antes do @ no e-mail (no entanto, na minha opinião, esses problemas potenciais são ou irrelevantes ou podem ser facilmente resolvidos pelo usuário).

4 curtidas

Além dos comentários de David acima, encontrei um tópico relacionado no site de suporte para desenvolvedores da Apple que recebeu uma resposta oficial confirmando o problema:

Resposta Oficial:

Olá aslkdjalksdjasdasd,
O comportamento está correto: as informações do usuário são enviadas apenas no ASAuthorizationAppleIDCredential durante o cadastro inicial do usuário. Logins subsequentes no seu aplicativo usando o “Entrar com Apple” com a mesma conta não compartilham nenhuma informação do usuário e retornarão apenas um identificador de usuário no ASAuthorizationAppleIDCredential. Recomendamos que você armazene em cache de forma segura o ASAuthorizationAppleIDCredential inicial contendo as informações do usuário até que possa validar que uma conta foi criada com sucesso no seu servidor.
Patrick

Como comenta um desenvolvedor:

Então espere… Se, por algum motivo, o primeiro redirecionamento da Apple se perder por uma das muitas razões MUITO comuns, perdemos permanentemente esse usuário, já que não há outra maneira de obter suas informações. Não existe OUTRA maneira de obter essas informações?

e outro:

Ou, se algo der errado a jusante, teremos clientes reclamando e o suporte dirá a eles para acessar o site do Apple ID para revogar a permissão, para que possam se registrar novamente corretamente. Acredito que isso será uma experiência ruim e fará com que as pessoas deixem de usar esse mecanismo de login se começarem a ter esse tipo de problema.

Portanto, não acho que seja seguro usar isso em produção, infelizmente. Isso seria um pesadelo para o suporte.

Sugiro que deixemos isso de lado até que a Apple perceba o problema que criou: em sua tentativa de melhorar a segurança, parece que eles comprometeram excessivamente a robustez.

11 curtidas

Que pena. :cry:

1 curtida

A Apple atualizou sua página de desenvolvedores “Entrar com a Apple” para incluir mais informações sobre coleta de dados, gerenciamento de dados, etc.

5 curtidas

Abri um pull request para atualizar o gem omniauth-apple para a versão mais recente, que inclui este commit que parece poder resolver o problema de não receber o e-mail do usuário em cada login.

Para testar isso, segui o post de blog recomendado para configurar as credenciais, mas há duas coisas que ainda não consegui entender:

  • Qual é o caminho da URL de redirecionamento de retorno necessária para configurar o ID do serviço com a Apple?
  • Como obtenho o “txt de verificação”, ou isso não é mais necessário? Ao pesquisar, encontrei menções de que isso poderia ser baixado da Apple como parte da configuração de comunicação de domínio/e-mail, mas parece que isso não é mais o caso:
3 curtidas

Obrigado.

Normalmente, você envia um PR após testar algo com sucesso :wink:

Por favor, confirme quando tiver feito isso.

Parece uma decisão óbvia, mas eu ficaria mais encorajado se tivéssemos uma declaração da Apple confirmando que eles agora enviam e-mails a cada vez. Alterar a versão do gem não resolverá isso se a Apple não tiver abordado o problema central.

Vou dar uma olhada na minha configuração quando me subscrever novamente como Desenvolvedor da Apple, o que ainda não fiz… (essa confusão foi um pouco desencorajadora, para ser sincero)

@David

Tentei atualizar nosso fork do plugin para usar a versão mais recente do omniauth-apple. (Note que há outras alterações necessárias, não apenas um aumento no número da versão).

tl;dr: ainda está quebrado

Consegui fazer funcionar com uma gambiarra no meu sandbox, mas ainda apresenta vários problemas:

  1. A Apple está usando uma requisição POST no callback. Isso não é comum em implementações OAuth, pois significa que cookies com samesite=Lax não serão enviados com a requisição. Isso impede que o Discourse leia os cookies de sessão durante o callback e, portanto, lança um erro CSRF.

    Uma solução INSEGURA é desabilitar essa segurança alterando os cookies do Discourse para samesite=None.

  2. Usar uma requisição POST sem um token CSRF também dispara outra medida de segurança no núcleo do sistema.

    Uma solução INSEGURA é remover esta linha.

  3. Estava recebendo um erro 403 da Apple quando o gem omniauth estava buscando os JWKs. Suspeito que o cabeçalho Accept: não esteja sendo definido corretamente, mas ainda não verifiquei isso.

    Uma solução INSEGURA foi codificar as chaves manualmente.

Após tudo isso, finalmente consegui fazer login com a Apple. Você pode testar em https://sandbox.dtaylor.uk (vou deixar funcionando por alguns dias, mas por favor, não insira nada sensível lá, pois é INSEGURO).

E então… e-mails e nomes ainda são incluídos apenas na primeira autenticação. Você pode testar isso: faça login com a Apple, cancele a criação da conta e tente novamente. Na segunda tentativa, seus dados estarão ausentes.

Então, supondo que a Apple não vá mudar nada em breve… como poderíamos fazer isso funcionar?

Para (1) e (2), acho que poderíamos converter o POST da Apple em um GET sem comprometer a segurança. Ao receber um POST no callback, renderizamos algum JavaScript que define window.location='/auth/apple/callback?code=...&state=...'. A partir daí, funcionaria como qualquer outro provedor. No entanto, acho que interceptar o POST exigiria algumas alterações na API central.

Para (3), acredito que isso poderia ser corrigido com um pouco de trabalho no gem omniauth.

Mas ainda estamos presos sem nome/e-mail, então não tenho certeza se vale a pena corrigir esses outros problemas :cry:

8 curtidas

Obrigado por tentar novamente e pela sua análise! Talvez abrir um incidente de suporte técnico na Apple possa esclarecer os problemas remanescentes? Pela minha experiência, eles tendem a fornecer soluções ou alternativas mais facilmente nesse canal do que nos fóruns de desenvolvedores da Apple.