Skip "Authorize application access"

We are using discourse as a collaboration tool and we have another app to search documents. We would like to integrate comments about documents into discourse. Both are using an external SSO/Oauth provider inside our infrastructure.

We are using the User API Key to connect the two apps so that they can communicate. It works fine but we have to click on this “Authorize application access” form that we would like to avoid because we are in a trusted environment backed with OAuth.

Is there a way that we could avoid this “authorize” access step, or bypass it and go directly to User API Key creation, so that this page does not display and the users don’t have to perform this extra step? Is there a parameter that we could provide in the request so that this step is bypassed?

We tried to call UserApiKeysController.create first (instead of UserApiKeysController.new) but we had a CSRF error. So we tried to skip the token check like :

class UserApiKeysController < ApplicationController
  skip_before_action :verify_authenticity_token

But it doesn’t work either.

Would you see another way of doing this ?

thanks in advance

Welcome here Bruno, nice to have you join us here :slight_smile: maybe @david or @blake have some ideas on this.

1 Like

I can certainly say this isn’t the correct way to go. Are you already using a plugin, or only interacting via HTTP?

If you’re using a plugin, you should not be interacting with app/controllers/ instances, for the most part.

If you’re interacting over HTTP, and using server-to-server communication, you would be better served with an Admin-created API key.

The User API is intended for client-to-server communication, where there is no way of providing code integrity over the client.

2 Likes

Yes we are planning to develop a discourse plugin and our JS app will interact only with HTTP requests.
We would like to avoid having to develop server-to-server communication (for ex with the use of admin API Key) to minimize coupling between components.

I understand that ideally we shouldn’t mess with discourse controllers and at the same time, there are a lot of methods that seems to be designed to be overridden (template method pattern and other extension points), and from what we’ve seen so far a lot of plugins are doing so.

So what would be the correct way to go ?

If you’re coding up a plugin, you should develop new routes in a plugin-mounted controller that directly perform the tasks you need. These routes can all share a before_action that sets the Access-Control-Allow-{Origin, Headers, Credentials} response headers (echo the Origin request header if it’s on the list of domains your app should be running on).

This way, your JS code can simply invoke fetch(..., { credentials: "include", ...}) with no API key at all.

2 Likes

Thanks @riking this works fine when we have an open session on discourse in the navigator.

We are able to initiate a new session by hand just calling http://discourse_site/login as we have SiteSetting.enable_local_logins = false and only one auth mechanism with oauth. The browser follows redirects on our oauth provider then redirects to discourse. It was what was happening under the hood when calling /user-api-key/new.

How could we initiate a new discourse session programmatically from the app if there is none ?