Omitir "Autorizar acceso a la aplicación"

Estamos utilizando Discourse como herramienta de colaboración y contamos con otra aplicación para buscar documentos. Nos gustaría integrar los comentarios sobre los documentos en Discourse. Ambas aplicaciones utilizan un proveedor externo de SSO/OAuth dentro de nuestra infraestructura.

Estamos utilizando la clave de API de usuario para conectar ambas aplicaciones y que puedan comunicarse. Funciona bien, pero tenemos que hacer clic en el formulario de “Autorizar acceso a la aplicación”, lo cual nos gustaría evitar ya que estamos en un entorno de confianza respaldado por OAuth.

¿Existe alguna forma de evitar este paso de “autorización” o eludirlo e ir directamente a la creación de la clave de API de usuario, de modo que esta página no se muestre y los usuarios no tengan que realizar este paso adicional? ¿Hay algún parámetro que podamos incluir en la solicitud para omitir este paso?

Intentamos llamar primero a UserApiKeysController.create (en lugar de UserApiKeysController.new), pero obtuvimos un error CSRF. Así que intentamos omitir la verificación del token de la siguiente manera:

class UserApiKeysController < ApplicationController
  skip_before_action :verify_authenticity_token

Pero tampoco funciona.

¿Se les ocurre alguna otra forma de hacerlo?

Gracias de antemano.

¡Bienvenido aquí, Bruno! Es un gusto tenerte con nosotros :slight_smile: Quizás @david o @blake tengan algunas ideas sobre esto.

1 me gusta

Puedo afirmar con seguridad que esta no es la forma correcta de proceder. ¿Ya estás utilizando un plugin o solo interactúas a través de HTTP?

Si estás utilizando un plugin, en la mayoría de los casos no deberías interactuar con instancias de app/controllers/.

Si estás interactuando a través de HTTP y utilizando comunicación de servidor a servidor, sería más adecuado utilizar una clave de API creada por un administrador.

La API de usuario está diseñada para la comunicación de cliente a servidor, donde no hay forma de garantizar la integridad del código en el cliente.

2 Me gusta

Sí, planeamos desarrollar un plugin para Discourse y nuestra aplicación JS interactuará únicamente mediante solicitudes HTTP.
Nos gustaría evitar tener que desarrollar comunicación entre servidores (por ejemplo, mediante el uso de una clave de API de administrador) para minimizar el acoplamiento entre componentes.

Entiendo que, idealmente, no deberíamos intervenir en los controladores de Discourse; al mismo tiempo, hay muchos métodos que parecen diseñados para ser sobrescritos (patrón de método plantilla y otros puntos de extensión), y por lo que hemos visto hasta ahora, muchos plugins lo hacen.

Entonces, ¿cuál sería la forma correcta de proceder?

Si estás desarrollando un plugin, deberías crear nuevas rutas en un controlador montado en el plugin que realicen directamente las tareas necesarias. Todas estas rutas pueden compartir un before_action que establezca las cabeceras de respuesta Access-Control-Allow-{Origin, Headers, Credentials} (devuelve la cabecera de solicitud Origin si está en la lista de dominios donde debería ejecutarse tu aplicación).

De esta manera, tu código JS simplemente podrá invocar fetch(..., { credentials: "include", ...}) sin necesidad de ninguna clave de API.

2 Me gusta

Gracias @riking, esto funciona bien cuando tenemos una sesión abierta en Discourse en el navegador.

Podemos iniciar una nueva sesión manualmente simplemente llamando a http://discourse_site/login, ya que tenemos SiteSetting.enable_local_logins = false y solo un mecanismo de autenticación con OAuth. El navegador sigue las redirecciones en nuestro proveedor de OAuth y luego redirige a Discourse. Esto es lo que ocurría internamente al llamar a /user-api-key/new.

¿Cómo podríamos iniciar una nueva sesión de Discourse programáticamente desde la aplicación si no existe ninguna?