Autologin com o Plugin OpenId Connect e AWS Cognito

Olá. Sou totalmente novo no Discourse. Tenho um aplicativo rodando na AWS que usa o Cognito para autenticação. Quero vincular esse aplicativo ao meu novo fórum hospedado no Discourse. Já dei um bom começo, mas espero que alguém possa fornecer orientação sobre os passos finais para fazer isso.

O objetivo é tornar a experiência de login perfeita entre meu aplicativo e o fórum do Discourse. Portanto:

  • Se um usuário estiver logado no meu aplicativo, quando ele acessar o fórum do Discourse, o Discourse reconhecerá isso e não exigirá um novo login.

  • Da mesma forma, se um usuário acessar primeiro o fórum do Discourse e não estiver logado, o Discourse o redirecionará para a página de login do meu aplicativo (ou para uma interface de login hospedada, se necessário).

O Plugin de Autenticação OpenID Connect parece ser bem adequado para isso. Me inscrevi no Plano Business do Discourse para garantir que posso usar esse plugin.

Segui as instruções fornecidas por @david e fiz o que acredito ser a configuração no lado do Cognito:

  1. No Cognito, obtive o “documento de descoberta do OpenID Connect” e o “client ID do OpenID Connect”.

  2. Nas configurações do meu Discourse, em openId_Connect, adicionei esses valores e os salvei.

  3. Marquei “habilitar autenticação OpenID Connect” e, em “escopo de autorização do OpenID Connect”, inseri “openid email”. Salvei essas configurações.

De acordo com a descrição do plugin, isso deveria estar pronto para uso, correto?

Bem, quando faço login no meu aplicativo e depois vou ao fórum, nada acontece. Apenas mostra a página inicial normal com os botões “inscrever-se” e “entrar”. Espero que ele me faça login automaticamente após verificar com o Cognito, mas não o faz. O que mais preciso fazer?

Além disso, se um usuário chegar ao site do fórum pela primeira vez (sem nunca ter feito login no meu aplicativo), ele não deve ver os botões de inscrição e login do Discourse; em vez disso, deve ver um botão que, ao ser clicado, o redirecionará para a página de login do meu aplicativo. Como adiciono isso?

E, finalmente, os usuários se inscrevem no meu aplicativo e pagam para usar recursos premium. Isso é salvo como atributos personalizados para o usuário no Cognito (há um atributo personalizado que diz “Inscrito” ou não). Apenas usuários inscritos devem poder postar no fórum. Portanto, quando o Discourse verificar com o Cognito para obter as informações do usuário, ele precisa verificar o atributo personalizado do usuário e, apenas se o usuário estiver inscrito, conceder a capacidade de postar. Como faço isso?

Como sou muito novo no Discourse, ficaria muito grato por qualquer informação que alguém tenha sobre qualquer uma dessas perguntas. Obrigado!

Olá @JQ331 :wave:

O login automático é suportado apenas se o seu site for privado (com a configuração do site login_required ativada).

Isso já deveria funcionar assim. Certifique-se de desativar todos os outros métodos de login, incluindo ‘logins locais’.

Infelizmente, isso não é possível usando o plugin OIDC.

@david, muito obrigado pela sua resposta. Isso é útil.

Onde está essa configuração de site “login_required”? Por “privado”, você quer dizer que os usuários só podem visualizar o conteúdo do site se estiverem logados? Obviamente, não é isso que eu quero aqui. Eu quero que seja apenas necessário estar logado para postar, e a única maneira de fazer login é através do meu aplicativo separado.

Eu assumo que você se refira em Configurações → Login → Habilitar logins locais (desmarque isso). Então, eu desmarquei tudo relacionado a logins locais. Mas o que devo marcar aqui? Por exemplo, se estou usando o plugin para vincular meu aplicativo separado para login, esse aplicativo separado é um “SSO” ou “OAuth2”? (Estou me perguntando, por exemplo, se devo selecionar “SSO substitui e-mail” ou “OAuth2 substitui e-mail”?)

Sobre apenas usuários pagantes poderem postar:

Essa é uma exigência fundamental, então talvez eu tenha que ser criativo. Existe outra opção além do plugin SSO? Se não, ainda consigo ver isso funcionando se uma dessas opções for possível:

  1. O Discourse tem diferentes níveis de permissão de usuário. Assim, eu poderia fazer com que um usuário pudesse estar logado, mas não tivesse permissão para realmente postar ou responder a posts. Nesse caso, eu precisaria definir o nível de permissão do usuário com base nas informações que o Discourse obtém do Cognito (se está ou não assinante).

  2. Se isso não funcionar, o Discourse tem um plugin Stripe funcional que permite que os usuários estejam logados, mas só possam postar se estiverem em dia com o pagamento através do sistema Stripe?

  3. Se nenhuma dessas opções funcionar — por exemplo, se o Discourse NÃO tiver a capacidade de distinguir entre níveis de privilégio de usuário que eu possa definir — então parece que eu teria que fazer com que um usuário esteja ou não logado, e apenas usuários logados possam postar. Isso faz sentido?

Se for esse o caso, então eu teria que descobrir, no lado do meu aplicativo, como instruir o Discourse a fazer login no usuário apenas se ele estiver em dia com os pagamentos no meu aplicativo.

Obrigado.

Nesse caso, o login automático não é atualmente suportado. Os usuários precisarão clicar no botão de login.

Ok, então agora o botão de login deve levar diretamente ao seu provedor de identidade. Isso está funcionando?

Sim, você pode configurar todas as suas categorias para que “todos” possam ler. Mas apenas usuários de um determinado grupo podem criar/responder a tópicos. Se você quiser automatizar isso, pode usar a API para adicionar/remover pessoas de um grupo.

Legal — parece que estou bem perto. Só para confirmar:

Quero que o seguinte seja verdade:

  1. Todos podem ler o conteúdo do site (logados ou não);
  2. Apenas usuários logados podem postar;
  3. Se você estiver logado no meu aplicativo, ao acessar o Discourse, ele se comunica com o Cognito e faz o login automaticamente, permitindo que você poste.

Você está dizendo que o item (3) não é possível? Você está dizendo que, por algum motivo, o login automático só ocorre se o conteúdo do site estiver oculto para o público?


Parece que é isso que quero fazer. Pelo que você disse “use a API”, imagino que você esteja sugerindo algo como:

  1. O usuário tenta fazer login no meu fórum.
  2. Ele é redirecionado para fazer login no meu aplicativo.
  3. Quando ele faz login no meu aplicativo, este verifica se ele está com a assinatura em dia. Se estiver, meu aplicativo faz uma chamada à API do Discourse para adicionar essa pessoa ao “grupo” que pode postar e responder.

É isso que você quer dizer? Se sim, existe alguma documentação principal para entender como adicionar pessoas a grupos por meio da API?

Obrigado, isso está me ajudando bastante a avançar.

Acho que talvez tenhamos definições diferentes de ‘login automático’.

O Discourse pode se conectar a um provedor OIDC para login. Esse processo é iniciado quando o usuário clica no botão ‘login’ no fórum. Isso sempre funciona, independentemente da configuração.

Se um site requer login (ou seja, a configuração ‘login obrigatório’ está ativada), o usuário é redirecionado diretamente para a tela de login do OIDC, sem precisar clicar no botão.

Sim, é isso que eu estava pensando. Aqui está alguma documentação sobre esse endpoint da API.

Legal. Obrigado! Vou dar uma olhada naquela documentação da API. Parece muito promissor.

Sobre a questão do “auto-login” — parece que você quis dizer “auto-login = enviar automaticamente o usuário para uma tela de login”. Então, pelo que entendi, quando um usuário acessa meu fórum Discourse, há duas opções:

Opção 1: O site “automaticamente” o redireciona para o login do aplicativo separado. Isso aconteceria independentemente de o usuário já estar logado no meu aplicativo ou não. (É isso que você descreveu como “auto-login”, e disse que isso ocorre se você definir “login_required”.)

Opção 2: O site não faz nenhum redirecionamento automático. Em vez disso, há um botão de login básico na página. Se o usuário clicar nesse botão ou tentar publicar, o fórum o redirecionará para o login do meu aplicativo.

Eu esperava pela Opção 3: Se o usuário estiver logado no meu aplicativo, ao acessar meu fórum Discourse, o fórum verifica no Cognito se o usuário está logado ou não. Se estiver logado no Cognito, o Discourse o autentica no fórum sem que o usuário precise fazer login novamente separadamente.

Sou novo no assunto OpenID, mas com certeza achei que isso fosse possível, porque se o usuário tiver que fazer login separadamente no aplicativo e também no fórum ao alternar entre os dois, a experiência não será fluida.

Não existe uma maneira de o fórum Discourse verificar no Cognito e ajustar o status de login do usuário sem que ele precise passar por um processo de login separado?

A propósito, estou assumindo que integrar o Discourse diretamente ao meu aplicativo não ajudaria. Eu faria isso se pudesse, mas parece que isso só é possível com iframes, o que não resolveria o problema de autenticação.

É tecnicamente possível na especificação OIDC, mas, infelizmente, o Discourse não suporta isso atualmente.

Hmm. Ouvi dizer que existem duas maneiras de fazer a ligação entre o Discourse e um provedor de autenticação externo, como o Cognito: o plugin OpenId ou usando o Single Sign On do Discourse.

Não tenho nenhuma familiaridade com o processo de Single Sign On, mas será que isso poderia ser uma forma de fazer o que eu quero — evitar que os usuários façam login duas vezes?

Ou talvez, simplesmente, quando eles fizerem login no meu aplicativo, enviar uma chamada de API ao Discourse e logá-los dessa maneira?

(O documento que linkei também fala sobre especificar a associação a grupos — presumo que isso accompliria o que eu quero, no sentido de dizer que apenas usuários PAGANTES podem estar no grupo que tem permissão para postar).