Expand my Community achievements bar.

SOLVED

How to generate oauth2 token using aio-lib-ims?

Avatar

Level 5

I am creating a simple runtime action, and trying to generate IMS oauth2 token 

 

import { context, getToken, getTokenData } from '@adobe/aio-lib-ims';
export async function getTokenUsingSDK() {
  const config = {
    client_id: clientId,
    client_secrets: clientSecret,
    technical_account_id: technicalAccountId,
    technical_account_email: technicalAccountEmail,
    ims_org_id: imsOrgId,
    scopes: OAUTH_TOKEN_SCOPES
  };
  await context.set('mynew-token', config);
  const token = await getToken('mynew-token');
  const tokenDecoded = getTokenData(token);
  logger.info('Token:' + JSON.stringify(tokenDecoded));
}

 

 It keeps failing as `400 Bad request`.

 

But same credentials from postman works. Below code using axios also works

 

export async function getTokenUsingAxios() {
  const url = "https://ims-na1.adobelogin.com/ims/token/v3";
  const headers = {
    "Content-Type": "application/x-www-form-urlencoded",
  };
  const data = qs.stringify({
    grant_type: OAUTH_TOKEN_GRANT_TYPE,
    client_id: clientId,
    client_secret: clientSecret,
    scope: SCOPES,
  });

  try {
    const response = await axios.post(url, data, { headers });
    return response.data;
  } catch (error) {
    logger.error("Error fetching token:", error);
    throw error;
  }
}

 

Now documentation also recommends to use 3rd party libraries. confusing. 

 

I assume, aio-lib-ims is the correct way to generate ims tokens. Need working code example to generate oauth2 server-to-server token. 

 

More context - security guidelines asks to generate token from browser and pass into runtime action as imsContext. In my case, I am creating non-webaction, that is subscribing and listening to journaling queue. Its cron, that runs every hour. I dont have browser to pass down imsContext. 

Creating new context with above config is not working. I am assuming only certain fields must be populated in config. It has been trial-n-error and unable to make this work. 

1 Accepted Solution

Avatar

Correct answer by
Level 5

I was just able to solve this myself. 

Secret was, the second param client_secrets is `Array` of secrets. The curl http request accepts as string. But SDK expects as array. And response error message was also not useful. 

 

Fix, was one-line `client_secrets: [clientSecret]`,

import { context, getToken, getTokenData } from '@adobe/aio-lib-ims';
export async function getTokenUsingSDK() {
  const config = {
    client_id: clientId,
    client_secrets: [clientSecret],
    technical_account_id: technicalAccountId,
    technical_account_email: technicalAccountEmail,
    ims_org_id: imsOrgId,
    scopes: OAUTH_TOKEN_SCOPES
  };
  await context.set('mynew-token', config);
  const token = await getToken('mynew-token');
  const tokenDecoded = getTokenData(token);
  logger.info('Token:' + JSON.stringify(tokenDecoded));
}

 This code works for me.

View solution in original post

1 Reply

Avatar

Correct answer by
Level 5

I was just able to solve this myself. 

Secret was, the second param client_secrets is `Array` of secrets. The curl http request accepts as string. But SDK expects as array. And response error message was also not useful. 

 

Fix, was one-line `client_secrets: [clientSecret]`,

import { context, getToken, getTokenData } from '@adobe/aio-lib-ims';
export async function getTokenUsingSDK() {
  const config = {
    client_id: clientId,
    client_secrets: [clientSecret],
    technical_account_id: technicalAccountId,
    technical_account_email: technicalAccountEmail,
    ims_org_id: imsOrgId,
    scopes: OAUTH_TOKEN_SCOPES
  };
  await context.set('mynew-token', config);
  const token = await getToken('mynew-token');
  const tokenDecoded = getTokenData(token);
  logger.info('Token:' + JSON.stringify(tokenDecoded));
}

 This code works for me.