Skip to content
Julian Waller edited this page Aug 10, 2023 · 1 revision

Some modules need to authenticate against an external service or API.
Companion does not currently have native support for OAuth, so modules are required to do the flow manually.

There are two key challenges to using OAuth with Companion:

  1. OAuth requires a stable redirect URL, the URL to access Companion can change daily
  2. The user needs to fill in various fields then navigate to a URL to begin the authentication.

Describe below is the current recommended way of supporting OAuth, but many existing modules are not using this. Expect this to be refined in the future, as support is improved

Handling the callback / redirect URL

OAuth needs a stable redirect URL, as it needs to be provided to both Companion and in the application settings you are connecting to.
To aid in this, a small redirector site has been created, which will help abstract this.

This is hosted at https://bitfocus.github.io/companion-oauth/callback. By providing your instance id (this.id) as the state parameter in the authentication url, the redirect site will help redirect the user to a http handler where you can access the generated authentication code.

To receive the authentication code, you should implement the [handleHttpRequest](HTTP handler) method, listening for the /oauth/callback path. An implementation can look like:

async handleHttpRequest(request) {
	if (request.path === '/oauth/callback') {
		const authCode = request.query['code']
		if (!authCode) {
			return {
				status: 400,
				body: 'Missing auth code!',
			}
		}

		if (!this.config.clientID || !this.config.clientSecret || !this.config.redirectURL) {
			return {
				status: 400,
				body: 'Missing required config fields!',
			}
		}

		try {
			// Exchange code for token

			// TODO: Implement your logic here
			
			//Save new values to Configuration
			this.log('info', 'Authentication Success, saving tokens')
			this.config.accessToken = response.data.accessToken
			this.config.refreshToken = response.data.refreshToken
			this.saveConfig(this.config)

			this.configUpdated(this.config)
		} catch (err) {
			this.log('debug', `Failed to get access token: ${err?.message ?? err?.toString()}`)
			return {
				status: 500,
				body: `Failed to authenticate\n${err?.message ?? err?.toString()}`,
			}
		}

		return {
			status: 200,
			body: 'Success!\nYou can close this tab',
		}
	}

	return {
		status: 404,
	}
}

Opening the authentication URL

The user needs to open the authentication URL to start the OAuth process.
As some users will be configuring their Companion remotely, you can't rely on being able to automatically open the url for them.

Most modules currently will put the needed URL in a config field for the user to access, and also write it to the log. Some will also open it automatically.

Clone this wiki locally