Cloud Run Script
February 12, 2023
/
3 min read
--- views
•
--- comments
Last Updated February 12, 2023
Prepare
- Generate and download a service account JSON key file.
- Copy and paste the contents of the JSON key file into the
serviceAccountKey
environment variable in a Postman environment. - Set the
baseUrl
collection variable in a Postman collection to the URL of your Cloud Run service. - Set the type of Authorization to
Bearer Token
and the value to{{idToken}}
in the Authorization tab of the Postman collection or request. - Copy and paste the contents of the
pre-request-script.js
file into the Pre-request Script tab of a Postman collection or request.
pre-request-script.js
Copy
const ENV_SERVICE_ACCOUNT_KEY = 'serviceAccountKey';
const ENV_JS_RSA_SIGN = 'jsrsasign';
const ENV_TOKEN_EXPIRES_AT = 'tokenExpiresAt';
const ENV_ID_TOKEN = 'idToken';
const VAR_SERVICE_URL = 'baseUrl'
const JS_RSA_SIGN_SRC = 'https://kjur.github.io/jsrsasign/jsrsasign-latest-all-min.js';
const GOOGLE_OAUTH = 'https://www.googleapis.com/oauth2/v4/token';
const EXPIRES_MARGIN = 300; // seconds before expiration
const getEnv = name =>
pm.environment.get(name);
const setEnv = (name, value) =>
pm.environment.set(name, value);
const getJWS = callback => {
// workaround for compatibility with jsrsasign
const navigator = {};
const window = {};
let jsrsasign = getEnv(ENV_JS_RSA_SIGN);
if (jsrsasign) {
eval(jsrsasign);
return callback(null, KJUR.jws.JWS);
}
pm.sendRequest(JS_RSA_SIGN_SRC, (err, res) => {
if (err) return callback(err);
jsrsasign = res.text();
setEnv(ENV_JS_RSA_SIGN, jsrsasign);
eval(jsrsasign);
callback(null, KJUR.jws.JWS);
});
};
const getJwt = ({ client_email, private_key }, serviceURL, iat, callback) => {
getJWS((err, JWS) => {
if (err) return callback(err);
const header = {
typ: 'JWT',
alg: 'RS256',
};
const exp = iat + 3600;
const payload = {
aud: GOOGLE_OAUTH,
iss: client_email,
sub: client_email,
iat,
exp,
target_audience: serviceURL
};
const jwt = JWS.sign(null, header, payload, private_key);
callback(null, jwt, exp);
});
};
const getToken = (serviceAccountKey, serviceURL, callback) => {
const now = Math.floor(Date.now() / 1000);
if (now + EXPIRES_MARGIN < pm.collectionVariables.get(ENV_TOKEN_EXPIRES_AT)) {
return callback();
}
getJwt(serviceAccountKey, serviceURL, now, (err, jwt, exp) => {
if (err) return callback(err);
const req = {
url: GOOGLE_OAUTH,
method: 'POST',
header: {
'Content-Type': 'application/x-www-form-urlencoded',
},
body: {
mode: 'urlencoded',
urlencoded: [{
key: 'grant_type',
value: 'urn:ietf:params:oauth:grant-type:jwt-bearer',
},{
key: 'assertion',
value: jwt,
}],
},
};
pm.sendRequest(req, (err, res) => {
if (err) return callback(err);
const idToken = res.json().id_token;
pm.collectionVariables.set(ENV_ID_TOKEN, idToken);
pm.collectionVariables.set(ENV_TOKEN_EXPIRES_AT, exp);
callback();
});
});
};
const getServiceAccountKey = callback => {
try {
const keyMaterial = getEnv(ENV_SERVICE_ACCOUNT_KEY);
const serviceAccountKey = JSON.parse(keyMaterial);
const serviceURL = pm.collectionVariables.get(VAR_SERVICE_URL);
callback(null, serviceAccountKey, serviceURL);
} catch (err) {
callback(err);
}
};
getServiceAccountKey((err, serviceAccountKey, serviceURL) => {
if (err) throw err;
getToken(serviceAccountKey, serviceURL, err => {
if (err) throw err;
});
});
Usage
Send the request and the idToken
and tokenExpiresAt
collection variables will automatically generated and cached in the collection. The idToken
will re-generate when it expires.