Authorization for Integration Recipes

Read more for a guide to designing your app's authorization flows.

Implementing Authorization in Integration Recipes

If you're building an integration with another tool (or multiple), chances are you will need to implement authorization. This article will walk you through how integration recipes handle authorization.

Default Behavior

By default, integration recipes do not require a specific authorization flow such as OAuth. When a user chooses a recipe in your app, they will be immediately directed to configure the recipe sentence and add it to their board.

Authorization Header

Every request from the Monday server to your app will be accompanied with a JWT token in the Authorization header. The token will be signed by your app's Signing Secret. The JWT token can be decoded to get additional metadata about the request.

You can decode the JWT token using a library like jsonwebtoken. The token will have this structure:

{
  "accountId": 1825528,
  "userId": 4012689,
  "aud": "https://www.yourserver.com/endpoint",
  "exp": 1606808758,
  "shortLivedToken": "SHORT_LIVED_TOKEN_HERE",
  "iat": 1606808458
}

📘

TIP

For more information about JSON Web Tokens, check out this link: Introduction to JWT.

Seamless Authentication

The JWT token will also contain a short-lived API key that that can be used to authenticate against the monday API. The token will be valid for 1 minute and have the same permission scopes as your app.

We will not issue a short-lived token if your app's endpoints do not start with https://.

When will monday send a request to my app?

The monday server will send a request to your app in six scenarios, all of which will contain the JWT token. Here are the six scenarios:

The Authorization URL

Optionally, you can specify an Authorization URL in the "Feature Details" section of your Integration feature. The Authorization URL is an endpoint on your server that directs users through your app's auth flow. When a user adds your integration recipe, they will be redirected to this Authorization URL.

Once the user arrives at your Authorization URL, your app can then pass them through one (or more) authorization flows, such as a 3rd party authorization flow or the monday.com OAuth flow .

Once the user has finished authorization and your app has the access tokens it needs, you should redirect them to the backToUrl to finish configuring the recipe.

The Authorization Token

When we redirect users to your Authorization URL, we will also pass your app a token query parameter. This parameter is a JWT token that is encoded with your app's Client Secret. The Client Secret can be found on your app's Basic Information page.

After verifying the token, its payload will contain three parameters:

  • userId - The User ID of the monday.com user you're authorizing
  • accountId - The Account ID of the user's monday.com account
  • backToUrl - This URL is where the user will finish configuring their recipe. Your app should redirect the user to the backToUrl after they have finished authorization.

Authorization URL Example

Here is an empty Node.js implementation that verifies the token and immediately redirects the user back to monday.

// The authorization route is /authorization
router.get("/authorization", (req, res) => { 
  // get the token from the query parameter
  const { token } = req.query; 

  // verify the JWT token
  const { userId, accountId, backToUrl } = jwt.verify(token, process.env.CLIENT_SECRET);

  // redirect the user
  return res.redirect(backToUrl);
});

Getting a monday.com Access Token

In some cases, your authorization process will need to get a long-term access token to the monday.com API from the user.

For that, your app should redirect the user to your app's monday.com OAuth URL, which will grant you an access token with the required scopes after the user approves access. You can then redirect the user to the Back To URL when the process is done. You can find the full OAuth documentation in our OAuth and Permissions article.

📘

NOTE

In order for your app to still have the "Back To URL" after the monday OAuth flow, you'll need to pass it (or the entire authorization token) through the state parameter of the monday OAuth request.

OAuth Flow Example

Here are two example endpoints to implement the flow. The first redirects the user to the OAuth Authorization URL, and the second is a callback URL that exchanges the OAuth authorization code for a token.

router.get("/authorization", (req, res) => {
  const { token } = req.query;
  return res.redirect('https://auth.monday.com/oauth2/authorize?' +
    querystring.stringify({
      client_id: process.env.CLIENT_ID,
      state: token
    })
  );
});

router.get("/oauth/callback", async (req, res) => {
  const { code, state } = req.query;
  const { userId, accountId, backToUrl } = jwt.verify(state, process.env.CLIENT_SECRET);

  // Get access token
  const token = await monday.oauthToken(code, process.env.CLIENT_ID, process.env.CLIENT_SECRET)
  
  // TODO - Store the token in a secure way in a way you'll can later on find it using the user ID. 
  // For example: await tokenStoreService.storeToken(userId, token);

  // Redirect back to monday
  return res.redirect(backToUrl);
});

Adding other services to your authorization flow

If your app integrates monday.com with another service, you might want to add additional authorization flows so your app can access the resources it needs. You can easily achieve that by redirecting the user to authorize one or more other services, using the same flow we showed in the previous section.

Like before, after your app has all the tokens and information it needs, you should redirect the user back to the Back To URL.

What about the next time the user adds my recipe?

The user will be redirected to your authorization URL every time they choose to add a recipe to their board. Your app can then check if the user has already been authenticated, and redirect them to the backToUrl instead of going through the authorization process again.

Here is an example that redirects the user immediately if your app already has an access token:

router.get("/authorization", (req, res) => {
  const { token } = req.query;
  const { userId, accountId, backToUrl } = jwt.verify(state, process.env.CLIENT_SECRET);

  // TODO - Check if you already have proper access token for that user
  // For example: const accessToken = await tokenStoreService.getToken(userId, token);

  if (accessToken) {
    return res.redirect(backToUrl) // redirect immediately
  } else {
    // redirect to monday.com OAuth URL
    return res.redirect('https://auth.monday.com/oauth2/authorize?' +
      querystring.stringify({
        client_id: process.env.CLIENT_ID,
        state: token
      })
    );
  }
});

What happens if my endpoints return an error?

If your app responds with a status code other than 200, monday will consider that an error. This is how each endpoint/scenario behaves in the case of an error:

  • Authorization URL - User will see your URL's error screen
  • Subscribe to custom trigger - User will see an error message in the monday.com UI
  • Unsubscribe to custom trigger - User will see an error message in monday.com
  • Call a custom action's Run URL - We will retry the request every minute for 30 mins
  • Remote options URL - User will see a “could not load fields” error message
  • Remote field defs in dynamic mapping - User will see “could not load fields” error

Did this page help you?