Automating Apigee SSO token generation for Postman requests

Making management API requests in Postman is a bit cumbersome when basic authentication is disabled in an on-premise installation. If a passcode is needed, the workflow involves first getting a passcode from Apigee SSO in a browser, getting an OAuth token with the get_token script and then setting it in Postman.

Here is a Postman script to generate SSO token in a pre-request script that can be attached to your API request or a folder or a collection. The script needs a passcode to first generate an access token, but for subsequent requests it will first try to reuse the access token (default validity is half an hour) or get a new access token with the refresh token (default validity is a day). If it cannot do that, it will get a new access token with a passcode and store that and the refresh token as environment variables for future use. If a token cannot be fetched, the script will throw an error and will not execute the API.

function getExistingOrNewToken() {
    if (pm.environment.get('BEARERTOKEN') && pm.environment.get('LAST_ACCESS_TOKEN_EXPIRY')) {
        console.log('Checking if previous bearer token is still valid');

        if ((new Date().valueOf() / 1000)  < pm.environment.get('LAST_ACCESS_TOKEN_EXPIRY') - 5) {
            console.log('Token is still valid.');
        } else {
            console.log('Token has expired. Trying to get new token with refresh token...');
            if (!pm.environment.get('REFRESHTOKEN')) {
                console.log('No refresh token found. Getting new token with passcode...');
                getNewTokenWithPasscode();
                return;;
            }
            if ((new Date().valueOf() / 1000)  < pm.environment.get('LAST_REFRESH_TOKEN_EXPIRY') - 5) {
                console.log('Refresh token is still valid.');
                const refreshTokenRequest = {
                    url: pm.environment.get('SSO_LOGIN_URL') + '/oauth/token',
                    method: 'POST',
                    header: {
                        'Authorization': 'Basic ZWRnZWNsaTplZGdlY2xpc2VjcmV0',
                        'Accept': 'application/json;charset=utf-8',
                        'Content-Type': 'application/x-www-form-urlencoded;charset=utf-8'
                    },
                    body: {
                        mode: 'urlencoded',
                        urlencoded: [
                            {key: "grant_type", value: "refresh_token", disabled: false},
                            {key: "refresh_token", value: pm.environment.get("REFRESHTOKEN"), disabled: false}
                        ]
                    }
                };
                console.log('Created new request: ' + refreshTokenRequest);
                performRequestAndStoreTokens(refreshTokenRequest)
            } else {
                console.log('Previous refresh token also has expired. Getting new token...')
                getNewTokenWithPasscode();        
            }
        }
    } else {
        console.log('No previous token found. Getting new token...')
        getNewTokenWithPasscode();
    }
}

function getNewTokenWithPasscode() {
    if (!pm.environment.get('PASSCODE')) {
        console.error('Passcode missing')
        throw new Error('PASSCODE environment variable is missing. Get a passcode from ' + pm.environment.get('SSO_LOGIN_URL') + '/passcode and set it.');
    }

    const tokenRequest = {
        url: pm.environment.get('SSO_LOGIN_URL') + '/oauth/token',
        method: 'POST',
        header: {
            'Authorization': 'Basic ZWRnZWNsaTplZGdlY2xpc2VjcmV0',
            'Accept': 'application/json;charset=utf-8',
            'Content-Type': 'application/x-www-form-urlencoded;charset=utf-8'
        },
        body: {
            mode: 'urlencoded',
            urlencoded: [
                {key: "grant_type", value: "password", disabled: false},
                {key: "response_type", value: 'token', disabled: false},
                {key: "passcode", value: pm.environment.get("PASSCODE"), disabled: false}
            ]
        }
    };
    performRequestAndStoreTokens(tokenRequest);
}

function performRequestAndStoreTokens(tokenRequest) {
    pm.sendRequest(tokenRequest, function (err, res) {
        console.log(err ? err : res.json());
        if (err === null) {
            if (res.code == 200) {
                var responseJson = res.json();
                console.log("Fetched new SSO token. Setting BEARERTOKEN = " + responseJson.access_token);
                pm.environment.set("BEARERTOKEN", responseJson.access_token);

                pm.environment.set("LAST_ACCESS_TOKEN_EXPIRY", JSON.parse(atob(responseJson.access_token.split('.')[1])).exp)

                pm.environment.set("REFRESHTOKEN", responseJson.refresh_token);
                
                pm.environment.set("LAST_REFRESH_TOKEN_EXPIRY", JSON.parse(atob(responseJson.refresh_token.split('.')[1])).exp)
            } else {
                console.error("Got non-success status code " + res.code);
                throw new Error(res.code + " - " + res.status + ". '" + res.json().error_description + "'. Get a new passcode from " + pm.environment.get('SSO_LOGIN_URL') + "/passcode and set as PASSCODE variable");
            }
        } else {
            console.error(err);
            throw new Error("Getting token failed due to " + err);
        }
    });
}

//Invoke script
getExistingOrNewToken();

Required Postman environment variables are SSO_LOGIN_URL (as in https://docs.apigee.com/api-platform/system-administration/auth-tools#install) and PASSCODE (when a new token has to be fetched).

In your API request (or folder or collection), set Authorization as Bearer Token or as OAuth 2.0 and set the token value as {{BEARERTOKEN}}. The script will set value of this variable.

Inspired by this StackOverflow answer - https://stackoverflow.com/a/55004018/10313610

Version history
Last update:
‎02-02-2021 01:41 AM
Updated by: