T-Mobile PoP Token Builder
npm install tmo-poptoken-builderThe T-Mobile PoP Token Builder library follows the following logic for creating the PoP token.
* Sets up the edts (external data to sign) / ehts (external headers to sign) claims in PoP token using the specified ehts key-value map. The library uses SHA256 algorithm for calculating the edts and then the final edts value is encoded using Base64 URL encoding.
* Signs the PoP token using the specified RSA private key.
* Creates the PoP token with 2 minutes of validity period.
* All required header and body fields and its values need to be defined.
* For HTTP request URI, "uri" should be used as ehts key name. Example: If the URL is https://api.t-mobile.com/commerce/v1/orders?account-number=0000000000 then only /commerce/v1/orders?account-number=0000000000 should be used as ehts value. The query parameter values part of "uri" ehts value should not be in URL encoded format.
* For HTTP method, "http-method" should be used as ehts key name.
* For HTTP request headers, the header name should be used as ehts key name.
* For HTTP request body, "body" should be used as ehts key name.
PoP token builder and validator libraries are currently supporting PKCS8 key format.
Below commands shows how to create private and public keys in PKCS8 format:
``bashCreates private key in PKCS1 format
openssl genrsa -out private-key-pkcs1.pem 2048
`
Link to the below JavaScript libraries in an HTML/client UI page
1. poptoken-builder.js (available in js_lib directory)jsrsasign-all-min.js
2. (available in root directory)
Sample Code
The following code snippet demonstrates how to use the PoP token builder Java Script library to build the PoP token. For the complete HTML/JS code, please refer to poptoken-builder-test.html available in html_example directory.
`
// Link the required JavaScript files
// The below command can be used to generate PKCS8 private key pem string
// openssl genrsa -out private-key-pkcs1.pem 2048
// openssl pkcs8 -topk8 -inform PEM -in private-key-pkcs1.pem -outform PEM -nocrypt -out private-key-pkcs8.pem
// openssl rsa -in private-key-pkcs8.pem -outform PEM -pubout -out public-key.pem
var privateKeyPemString = "" +
"-----BEGIN PRIVATE KEY-----\n" +
"MIIEvAIBADANBgkqhkiG9w0BAQEFAASCBKYwggSiAgEAAoIBAQC2ccmjG1gBJwTN\n" +
"slQJAEYmQYZl0j2LI+URPXCOjWj3hcmjYQPdfd+ZeCKuA8aUgXFox1xBdIxqAnY4\n" +
"8pW0MyMlwtyOiMpcnelzuKl9CqktbLSxdOUDo/wOd2d4lKnuvIHSKeoETfENroVM\n" +
"3Cm3CFJ8tmpQRjMYh4MBxZh2V3XClhES8t12DI+Lznr5BWvk8oIjRRs99Xu2n9Dy\n" +
"RoYal3trb+0ncdmr5EDhDE/sBC6MAk37UjyS8sty37+tbcgLkn42WISemSLnA4IO\n" +
"yiW6EZHcSTXj/vUCHLJjwDyihMCUWfA6NxLPlPFcLaD4o8DEg2VOa89rL9t1SoBo\n" +
"wsEhLn/5AgMBAAECggEBAI0tReOSMCpMIDpvyPliHeZShAZchsUZlJMfoO6eXGBV\n" +
"Ra/ITa5iTdk7DlLrlwmplLGIu0nnPxR1LThp9xAHFiaNQBCHp1e91j124qhgzILb\n" +
"AIPlOaX0igJDwWycVVboxeh0CKMmEOcOahYMs7bvmKzqlx/hAn7ztZt0ZMMGcJiO\n" +
"KLIUBVOjFoCeDoLgjvNrBduvHCnQ2CcJLnBxml7oRYc63ipBeJmC+aGjCIdKGtFK\n" +
"WRGiYrM4n5h4CKEnMTaZ+KAkJTmS43CBobDbp+rJbfpsGo7+xCt1VyjZfpMjF3zB\n" +
"oK8LywuFDddwopcMMkCHbFo7sM9HBqW7vyzgxlBZ5QECgYEA8f6XN2o9QV57H6GO\n" +
"5X0tCe5zdHt4NIHGYJfC3gVkduurMg8q/DBHBodFokp53OC48zOh6NzJOyhWacLq\n" +
"H6oSLQy2oSIBIXKC3Wt9yreOa3g69tQTN+CT7OT87KMvV0nYf7lXWTxjgMLEgClh\n" +
"0tDDls3+03oIQ4FpP7LBc6WhhRkCgYEAwQDmOtAYP51xuuVXl3Z0x9r6xfeIq/NG\n" +
"IqlVcq6tB+yWJ+YtVoysboyTcfJbGCPRMeQlrntfHSkdjMWb8R+xwt5c0eAmcL8m\n" +
"9tEtjHFa2QkqbKkQ3wRmS6KXJ8WJGY2opnVPwpWHpJn2qg01NkgQFfkjgUkWPSZx\n" +
"oauKcjiwTeECfx1NtwH+22wPBNnPtn4TqmCJf3GbgfLZxCvuNKqt/HxqDVEChTIE\n" +
"ppUjzErauecFT2Aj4HdSRQvk1pH4CGHNNmY+I99fPsPOGgq1+YWStKxO4tUA2VLq\n" +
"3v7Qu8/r8s+fIZhV2T31EheFfkYGvNHKdeTNDQ6OuHF0Okp8WvCmHekCgYEAtfW+\n" +
"GXa1Vcx/O+AbG54/bWjDgr7j6JE771PMTonmchEYY9d7qRyJONRp8kS2o2SpRqs8\n" +
"52pC+wAXbu+jHMpv0jPIOMpmE2f0OUBu+/im2PXuPHGMiWXhd697aLCwmBnZBc6V\n" +
"+vL05jeNuTcoktuP5tdzJOGeCNrkyLIsnZFajqECgYAGEbakt+8OpDxFVIFzPWGT\n" +
"f2KIeBYHX74JiJ3C0iGYvTiIO2cPuM3sSzUfx6+kmCqKioLueMW6BcAIy0WdELOh\n" +
"P1MaK10FQ12qFFrsnOZjVPoxZ4xVtzN3e4uCyc69xT2bAUpzoVKCMaCSRNv/unGk\n" +
"zHNmq7/VPITL5UgtZ5nk6g==\n" +
"-----END PRIVATE KEY-----\n";
// STEP 1: Build the Javascript Map of ehts (external headers to sign) key and values
mapehtsKeyValue.set('Content-Type', 'application/json');
mapehtsKeyValue.set('Authorization', 'Bearer UtKV75JJbVAewOrkHMXhLbiQ11SS');
mapehtsKeyValue.set('uri', '/commerce/v1/orders');
mapehtsKeyValue.set('http-method', 'POST');
mapehtsKeyValue.set('body', '{"orderId": 100, "product": "Mobile Phone"}');
The validity of 2 minutes has been defined in the method. It can be changed as required.
// STEP 2: Generate PoP token using PoPTokenBuilder
var popToken = '';
var ehtsKeyValuMap = new Map();
setEhtsKeyValueMap(ehtsKeyValuMap);
popToken = buildPopToken(ehtsKeyValuMap, privateKeyPemString);
`
Install the node modules using the following command
`bash`
npm install
The above command will create node_modules directory and will install the necessary node modules in it.
Sample Code
The following code snippet demonstrates how to use the PoP token builder Java Script library to build the PoP token. For the complete Node.js sample code, please refer to index-poptoken-builder.js available in node_example directory.
`js
var popTokenBuilderUtil = require('../poptoken-builder-node');
var popToken = '';
var ehtsKeyValueMap = new Map();
ehtsKeyValueMap.set('Content-Type', 'application/json');
ehtsKeyValueMap.set('Authorization', 'Bearer UtKV75JJbVAewOrkHMXhLbiQ11SS');
ehtsKeyValueMap.set('uri', '/commerce/v1/orders');
ehtsKeyValueMap.set('http-method', 'POST');
ehtsKeyValueMap.set('body', '{"orderId": 100, "product": "Mobile Phone"}');
var privateKeyPemStr = "" +
"-----BEGIN PRIVATE KEY-----\n" +
"MIIEvAIBADANBgkqhkiG9w0BAQEFAASCBKYwggSiAgEAAoIBAQC2ccmjG1gBJwTN\n" +
"slQJAEYmQYZl0j2LI+URPXCOjWj3hcmjYQPdfd+ZeCKuA8aUgXFox1xBdIxqAnY4\n" +
"8pW0MyMlwtyOiMpcnelzuKl9CqktbLSxdOUDo/wOd2d4lKnuvIHSKeoETfENroVM\n" +
"3Cm3CFJ8tmpQRjMYh4MBxZh2V3XClhES8t12DI+Lznr5BWvk8oIjRRs99Xu2n9Dy\n" +
"RoYal3trb+0ncdmr5EDhDE/sBC6MAk37UjyS8sty37+tbcgLkn42WISemSLnA4IO\n" +
"yiW6EZHcSTXj/vUCHLJjwDyihMCUWfA6NxLPlPFcLaD4o8DEg2VOa89rL9t1SoBo\n" +
"wsEhLn/5AgMBAAECggEBAI0tReOSMCpMIDpvyPliHeZShAZchsUZlJMfoO6eXGBV\n" +
"Ra/ITa5iTdk7DlLrlwmplLGIu0nnPxR1LThp9xAHFiaNQBCHp1e91j124qhgzILb\n" +
"AIPlOaX0igJDwWycVVboxeh0CKMmEOcOahYMs7bvmKzqlx/hAn7ztZt0ZMMGcJiO\n" +
"KLIUBVOjFoCeDoLgjvNrBduvHCnQ2CcJLnBxml7oRYc63ipBeJmC+aGjCIdKGtFK\n" +
"WRGiYrM4n5h4CKEnMTaZ+KAkJTmS43CBobDbp+rJbfpsGo7+xCt1VyjZfpMjF3zB\n" +
"oK8LywuFDddwopcMMkCHbFo7sM9HBqW7vyzgxlBZ5QECgYEA8f6XN2o9QV57H6GO\n" +
"5X0tCe5zdHt4NIHGYJfC3gVkduurMg8q/DBHBodFokp53OC48zOh6NzJOyhWacLq\n" +
"H6oSLQy2oSIBIXKC3Wt9yreOa3g69tQTN+CT7OT87KMvV0nYf7lXWTxjgMLEgClh\n" +
"0tDDls3+03oIQ4FpP7LBc6WhhRkCgYEAwQDmOtAYP51xuuVXl3Z0x9r6xfeIq/NG\n" +
"IqlVcq6tB+yWJ+YtVoysboyTcfJbGCPRMeQlrntfHSkdjMWb8R+xwt5c0eAmcL8m\n" +
"9tEtjHFa2QkqbKkQ3wRmS6KXJ8WJGY2opnVPwpWHpJn2qg01NkgQFfkjgUkWPSZx\n" +
"oauKcjiwTeECfx1NtwH+22wPBNnPtn4TqmCJf3GbgfLZxCvuNKqt/HxqDVEChTIE\n" +
"ppUjzErauecFT2Aj4HdSRQvk1pH4CGHNNmY+I99fPsPOGgq1+YWStKxO4tUA2VLq\n" +
"3v7Qu8/r8s+fIZhV2T31EheFfkYGvNHKdeTNDQ6OuHF0Okp8WvCmHekCgYEAtfW+\n" +
"GXa1Vcx/O+AbG54/bWjDgr7j6JE771PMTonmchEYY9d7qRyJONRp8kS2o2SpRqs8\n" +
"52pC+wAXbu+jHMpv0jPIOMpmE2f0OUBu+/im2PXuPHGMiWXhd697aLCwmBnZBc6V\n" +
"+vL05jeNuTcoktuP5tdzJOGeCNrkyLIsnZFajqECgYAGEbakt+8OpDxFVIFzPWGT\n" +
"f2KIeBYHX74JiJ3C0iGYvTiIO2cPuM3sSzUfx6+kmCqKioLueMW6BcAIy0WdELOh\n" +
"P1MaK10FQ12qFFrsnOZjVPoxZ4xVtzN3e4uCyc69xT2bAUpzoVKCMaCSRNv/unGk\n" +
"zHNmq7/VPITL5UgtZ5nk6g==\n" +
"-----END PRIVATE KEY-----\n";
popToken = popTokenBuilderUtil.buildPopToken(ehtsKeyValueMap, privateKeyPemStr);
console.log("The JWT for the given RSA PEM is - " + popToken);
`
The public/private key pair can be created using the following sample code. This sample code can be found at node_example/create-key-pair/index-create-key-pair.js.
`js
const { generateKeyPair } = require('crypto');
var fs = require("fs");
generateKeyPair('rsa', {
modulusLength: 2048,
publicKeyEncoding: {
type: 'spki',
format: 'pem'
},
privateKeyEncoding: {
type: 'pkcs8',
format: 'pem'
}
}, (err, publicKey, privateKey) => {
fs.writeFile('public-key.txt', publicKey, (err) => {
if (err) {
throw err;
} else {
console.log('The public-key.txt file has been saved.');
}
});
fs.writeFile('private-key.txt', privateKey, (err) => {
if (err) {
throw err;
} else {
console.log('The private-key.txt file has been saved.');
}
});
});
``