Renewable OAuth to Dataverse with Postman

Have you ever used Postman to access your Microsoft Dataverse environment’s Web API? Postman makes it incredibly convenient to execute web requests and share common APIs with your team. By creating an application user, you can grant your custom apps access to Dataverse in scenarios where you can’t authenticate individual users. You can then authorize Dataverse requests using your client credentials and OAuth 2.0.

“This is all well and good,” you’re saying, “but have you seen the OAuth settings in Postman? I have no clue what I’m doing!” Fear not, fictional version of you that I made for the sake of argument. We took care of the hard part, so you can click the link and get straight to the Dataverse stuff that really matters.  

However, if you are more experienced with Postman and have even seen the Microsoft documentation around how to use it with Dataverse, you might wonder what we are adding.  The script below highlights the key addition: automatically renewing the access token when it expires.

// Refresh OAuth token if it has expired.
// Modified from https://medium.com/@allen.helton/how-to-automate-oauth2-token-renewal-in-postman-864420d381a0
var tokenDate = new Date(2010,1,1);
var tokenTimestamp = pm.environment.get('_oauthTimestamp');
if (tokenTimestamp) {
    tokenDate = Date.parse(tokenTimestamp);
}
var expiresInTime = pm.environment.get('_expiresInTime');
if (!expiresInTime) {
    expiresInTime = 300000; // Set default expiration time to 5 minutes
}
if ((new Date() - tokenDate) >= expiresInTime) 
{
    var unencodedAuth = pm.environment.get('clientId') + ':' + pm.environment.get('clientSecret');
    var encodedAuth = 'Basic ' + btoa(unencodedAuth);
    var scope = pm.environment.get('dataverseBase') + '/.default';
    pm.sendRequest({
        url:  pm.environment.get('authUrl'), 
        method: 'POST',
        header: {
            'Accept': 'application/json',
            'Content-Type': 'application/x-www-form-urlencoded',
            'Authorization': encodedAuth
        },
        body: 'grant_type=client_credentials&scope=' + encodeURIComponent(scope)
    }, function (err, res) {
        var responseBody = res.json();
        pm.environment.set('_oauthToken', responseBody.access_token);
        pm.environment.set('_oauthTimestamp', new Date());
        
        // Set the ExpiresInTime variable to the time given in the response if it exists
        if (responseBody.expires_in) {
            expiresInTime = responseBody.expires_in * 1000;
        }
        pm.environment.set('_expiresInTime', expiresInTime);
    });
}

Again, if this all seems like too much or you are new to Postman, the quick start instructions include a simple request collection and environment variables. Already have a request collection that you want to improve? Try these instructions to set it up yourself. Either way, you should be good to go in no time.