Inicio de sesión automático con el plugin OpenId Connect y AWS Cognito

Hola. Soy nuevo en Discourse. Tengo una aplicación ejecutándose en AWS que utiliza Cognito para la autenticación. Quiero vincular esta aplicación a mi nuevo foro alojado en Discourse. He dado un buen comienzo, pero espero que alguien pueda brindarme orientación sobre los pasos finales para lograrlo.

El objetivo es que la experiencia de inicio de sesión sea fluida entre mi aplicación y el foro de Discourse. Por lo tanto:

  • Si un usuario ha iniciado sesión en mi aplicación, cuando vaya al foro de Discourse, este lo reconocerá y no requerirá un nuevo inicio de sesión.

  • De manera similar, si un usuario va primero al foro de Discourse y no ha iniciado sesión, Discourse lo redirigirá a la página de inicio de sesión de mi aplicación (o a una interfaz de usuario de inicio de sesión alojada si es necesario).

El Plugin de autenticación OpenId Connect parece estar bien diseñado para esto. Me he registrado en un Plan Empresarial con Discourse para asegurarme de poder usar este plugin.

He seguido las instrucciones proporcionadas por @david y he realizado lo que creo que es la configuración en el lado de Cognito:

  1. Desde Cognito, he obtenido el “documento de descubrimiento de OpenID Connect” y el “client id de OpenID Connect”.

  2. En la configuración de mi Discourse, bajo openId_Connect, los he agregado y guardado.

  3. He marcado “habilitar autenticación OpenID Connect” y, bajo el ámbito de autorización de OpenID Connect, he ingresado “openid email”. He guardado esta configuración.

Según la descripción del plugin, ¿esto debería ser suficiente, correcto?

Bueno, cuando inicio sesión en mi aplicación y luego voy a mi foro, no sucede nada. Solo muestra la página de inicio normal con los botones “registrarse” e “iniciar sesión”. Espero que me inicie sesión automáticamente después de verificar con Cognito, pero no lo hace. ¿Qué más necesito hacer?

Además, si un usuario llega al sitio del foro por primera vez (sin haber iniciado sesión nunca en mi aplicación), no debería ver los botones de registro e inicio de sesión de Discourse; en su lugar, debería ver un botón que, al hacer clic, lo redirija a la página de inicio de sesión de mi aplicación. ¿Cómo agrego esto?

Y finalmente, los usuarios se suscriben a mi aplicación y pagan para usar funciones premium. Esto se guarda como atributos personalizados para el usuario en Cognito (hay un atributo personalizado que indica si está suscrito o no). Solo los usuarios suscritos deberían poder publicar en el foro. Por lo tanto, cuando Discourse verifica con Cognito para obtener la información del usuario, debe verificar el atributo personalizado del usuario y, solo si el usuario está suscrito, otorgarle la capacidad de publicar. ¿Cómo lo hago?

Al ser tan nuevo en Discourse, agradecería mucho cualquier información que alguien tenga sobre cualquiera de estas preguntas. ¡Gracias!

Hola @JQ331 :wave:

El inicio de sesión automático solo es compatible si tu sitio es privado (tiene la configuración de sitio login_required habilitada).

Esa debería ser la forma en que ya funciona. Asegúrate de deshabilitar todos los demás métodos de inicio de sesión, incluidos los “inicios de sesión locales”.

Desafortunadamente, esto no es posible utilizando el complemento OIDC.

@david, muchas gracias por tu respuesta. Esto es muy útil.

¿Dónde está esta configuración del sitio “login_required”? ¿Con “privado”, te refieres a que los usuarios solo pueden ver el contenido del sitio si han iniciado sesión? Obviamente, eso no es lo que quiero aquí. Quiero que sea solo que tengas que iniciar sesión para publicar, y la única forma de iniciar sesión es a través de mi aplicación separada.

Supongo que te refieres a Configuración → Inicio de sesión → Habilitar inicios de sesión locales (desmarcar esto). Entonces, he desmarcado todo lo relacionado con el inicio de sesión local. Pero, ¿qué debería marcar aquí? Por ejemplo, si estoy usando el plugin para vincular mi aplicación separada para el inicio de sesión, ¿esa aplicación separada es “SSO” o “OAuth2”? (Me pregunto, por ejemplo, si debo seleccionar “SSO anula el correo electrónico” o “OAuth2 anula el correo electrónico”?

Sobre que solo los usuarios de pago puedan publicar:

Este es un requisito fundamental, así que tal vez tenga que ser creativo. ¿Hay otra opción aparte del plugin SSO? Si no, todavía podría ver que esto funcione si es posible una de estas opciones:

  1. Discourse tiene diferentes niveles de permisos de usuario. De modo que podría hacer que un usuario pueda haber iniciado sesión, pero no tener permiso para publicar o responder a publicaciones. En este caso, tendría que establecer el nivel de permiso del usuario en función de la información que Discourse obtiene de Cognito (si está suscrito o no).

  2. Si eso no funciona, ¿tiene Discourse un plugin de Stripe funcional que permita a los usuarios iniciar sesión, pero solo puedan publicar si han pagado a través del sistema de Stripe?

  3. Si ninguna de estas opciones funciona (por ejemplo, si Discourse NO tiene la capacidad de distinguir entre niveles de privilegio de usuario que pueda configurar), entonces parece que tendría que hacer que un usuario esté o no haya iniciado sesión, y solo los usuarios que han iniciado sesión puedan publicar. ¿Suena bien?

Si ese es el caso, entonces tendría que averiguar por mi cuenta en el extremo de mi aplicación cómo decirle a Discourse que solo inicie sesión en el usuario si está pagado en mi aplicación.

Gracias.

En ese caso, el inicio de sesión automático no es compatible actualmente. Los usuarios tendrán que hacer clic en el botón de iniciar sesión.

De acuerdo, ahora el botón de iniciar sesión debería enlazar directamente a tu proveedor de identidad. ¿Funciona?

Sí, podrías configurar todas tus categorías para que “todos” puedan leer. Pero solo los usuarios de un grupo determinado podrán crear o responder temas. Si deseas automatizarlo, podrías usar la API para agregar o eliminar personas de un grupo.

Genial, parece que estoy bastante cerca. Solo para confirmar:

Quiero que se cumpla lo siguiente:

  1. Todo el mundo puede leer el contenido del sitio (iniciado sesión o no).
  2. Solo los usuarios iniciados en sesión pueden publicar.
  3. Si has iniciado sesión en mi aplicación, al ir a Discourse, esta se comunica con Cognito e inicia sesión automáticamente, permitiéndote publicar.

¿Estás diciendo que (3) no es posible? ¿Estás diciendo que, por alguna razón, el inicio de sesión automático solo ocurre si el contenido del sitio está oculto para el público?


Suena como lo que quiero hacer. Por tu mención de “usar la API”, supongo que te refieres a algo así:

  1. El usuario intenta iniciar sesión en mi foro.
  2. Es redirigido para iniciar sesión en mi aplicación.
  3. Cuando inicia sesión en mi aplicación, esta verifica si ha pagado o no. Si ha pagado, mi aplicación realiza una llamada a la API de Discourse para agregar a esa persona al “grupo” que puede publicar y responder.

¿Es eso a lo que te refieres? De ser así, ¿hay una documentación de referencia para entender cómo agregar personas a grupos mediante la API?

Gracias, esto me está ayudando mucho a avanzar.

Creo que quizás tenemos definiciones diferentes de “inicio de sesión automático”.

Discourse puede conectarse a un proveedor OIDC para el inicio de sesión. Este proceso se inicia cuando el usuario hace clic en el botón “Iniciar sesión” en el foro. Esto siempre funciona, independientemente de la configuración.

Si un sitio requiere inicio de sesión (es decir, la configuración “requerir inicio de sesión” está habilitada), el usuario es redirigido directamente a la pantalla de inicio de sesión de OIDC sin necesidad de hacer clic en el botón.

Sí, eso es lo que pensaba. Aquí tienes documentación sobre ese punto de la API.

Genial. ¡Gracias! Voy a revisar esa documentación de la API. Parece muy prometedora.

Sobre lo de “inicio de sesión automático”—parece que te refieres a “inicio de sesión automático = enviar automáticamente al usuario a una pantalla de inicio de sesión”. Entonces, lo que dices es que cuando un usuario va a mi foro de Discourse, hay dos opciones:
Opción 1. El sitio “automáticamente” los envía al inicio de sesión de la aplicación separada. Esto ocurriría independientemente de si el usuario ya ha iniciado sesión en mi aplicación o no. (Esto es lo que describes como “inicio de sesión automático”, y mencionas que ocurre si configuras “login_required”).

Opción 2. El sitio no realiza ninguna redirección automática. En su lugar, hay un botón de inicio de sesión básico en la página. Si un usuario hace clic en ese botón o intenta publicar, el foro los redirigirá al inicio de sesión de mi aplicación.

Yo esperaba la Opción 3: Si un usuario ha iniciado sesión en mi aplicación, cuando vaya a mi foro de Discourse, este verificará en Cognito si el usuario está autenticado o no. Si ya está autenticado en Cognito, entonces Discourse lo iniciará sesión en el foro sin que el usuario tenga que volver a iniciar sesión por separado.

Soy nuevo en lo de OpenID, pero definitivamente pensé que esto era posible, porque si un usuario tiene que iniciar sesión por separado en la aplicación y también en el foro al cambiar entre ambos, no es una experiencia fluida.

¿No hay alguna manera de que el foro de Discourse verifique con Cognito y ajuste el estado de inicio de sesión del usuario sin que este tenga que pasar por un proceso de inicio de sesión separado?

Por cierto, asumo que integrar Discourse directamente en mi aplicación no ayudaría. Lo haría si pudiera, pero parece que esto solo es posible con iframes, y eso no resolvería el problema de autenticación.

Técnicamente es posible según la especificación OIDC, pero, por desgracia, Discourse no lo admite actualmente.

Hmm. He oído que hay dos formas de establecer el enlace entre Discourse y un proveedor de autenticación externo como Cognito: el plugin OpenId o utilizando Single Sign On para Discourse.

No estoy familiarizado en absoluto con el proceso de Single Sign On, pero ¿podría ser una forma de lograr lo que quiero, es decir, evitar que los usuarios inicien sesión dos veces?

¿O quizás, simplemente, cuando se registren en mi aplicación, enviar una llamada API a Discourse y registrarlos de esa manera?

(La documentación que enlazo también habla de especificar la pertenencia a grupos; supongo que eso lograría lo que quiero en cuanto a establecer que solo los usuarios que PAGAN pueden estar en el grupo autorizado para publicar).