Fronzie
Fronzie

Reputation: 33

Get Microsoft GRAPH access token from Nodejs script

This question builds on How to get Microsoft Graph API Access token from Node Script?, however, as a first-time user of, I don't have the required reputation for commenting on the accepted answer in that thread.

The thing is, I tried to implement the approach suggested by the accepted answer, but somewhere it goes wrong. The below code is part of an async function, and I can already tell you that the ONEDRIVE_TENANT_URI is of the format XXX.onmicrosoft.com.

const endpoint = `https://login.microsoftonline.com/${process.env.ONEDRIVE_TENTANT_URI}/oauth2/token`;
const requestParams = {
  grant_type: "client_credentials",
  client_id: process.env.ONEDRIVE_APP_ID,
  client_secret: process.env.ONEDRIVE_CLIENT_SECRET,
  resource: "https://graph.windows.net"
};

const authResponse = await request.post({
  url: endpoint,
  form: requestParams
});

authResponse gets, as its body, just a string with the requestParams as defined above filled out.

If I submit the post request via Postman, with the same parameters as x-www-form-urlencoded, I DO get an access_token in the response body.

So... What do I do wrong? Maybe - but I don't think so - it's because this function is invoked by a (for testing purposes) POSTMAN GET request with a json-formatted body?

Upvotes: 2

Views: 1755

Answers (2)

Marc LaFleur
Marc LaFleur

Reputation: 33094

You've got two issues going on.

The first isn't an issue yet, but it will be once you try to call Microsoft Graph. The resource should be graph.microsoft.net, not graph.windows.net. The graph.windows.net refers to the legacy Azure AD Graph API, not Microsoft Graph.

The other issue, which is the root cause of this error, is await request.post. Request doesn't natively support promises. From the Request the documentation:

request supports both streaming and callback interfaces natively. If you'd like request to return a Promise instead, you can use an alternative interface wrapper for request. These wrappers can be useful if you prefer to work with Promises, or if you'd like to use async/await in ES2017.

Several alternative interfaces are provided by the request team, including:

Upvotes: 1

Tony Ju
Tony Ju

Reputation: 15609

You can download the sample here. And fill in the credentials in config.js. You can find them from Azure portal. enter image description here

This is the code to get access token.

auth.getAccessToken = function () {
  var deferred = Q.defer();

  // These are the parameters necessary for the OAuth 2.0 Client Credentials Grant Flow.
  // For more information, see Service to Service Calls Using Client Credentials (https://msdn.microsoft.com/library/azure/dn645543.aspx).
  var requestParams = {
    grant_type: 'client_credentials',
    client_id: config.clientId,
    client_secret: config.clientSecret,
    resource: 'https://graph.microsoft.com'
  };

  // Make a request to the token issuing endpoint.
  request.post({ url: config.tokenEndpoint, form: requestParams }, function (err, response, body) {
    var parsedBody = JSON.parse(body);
    console.log(parsedBody);
    if (err) {
      deferred.reject(err);
    } else if (parsedBody.error) {
      deferred.reject(parsedBody.error_description);
    } else {
      // If successful, return the access token.
      deferred.resolve(parsedBody.access_token);
    }
  });

  return deferred.promise;
};

You will get the access token successfully. enter image description here

Upvotes: 1

Related Questions