JSFiddle - React, Tailwind, and code Playground
by joshAtDoorDash
HTML
<script src="https://cdnjs.cloudflare.com/ajax/libs/crypto-js/4.1.1/crypto-js.min.js"></script>
<h2>DoorDash Merchant Values</h2>
<i>Values provided on <a href="https://developer.doordash.com/portal/integration/drive/credentials">DoorDash API Credentials</a> page.</i>
<br /> <br />
<table>
<tr>
<td><label>Developer ID</label></td>
<td><input type="text" id="developerId" size="40"></td>
</tr>
<tr>
<td><label>Key ID</label></td>
<td><input type="text" id="keyId" size="40"></td>
</tr>
<tr>
<td><label>Signing Secret</label></td>
<td>
<input type="password" id="signingSecret" size="50">
</td>
</tr>
<tr>
<td> </td>
<td>
<button onclick="updateJWT()">Update JWT</button>
</td>
</tr>
</table>
<h2>JWT Parts</h2>
<p>
JWTs (JSON Web Tokens) consist of three parts which include the Header, Payload, and Signature. The following displays each of the these parts.
</p>
<table>
<tr>
<td style="overflow:hidden; width:50px;">
<label>Header</label><br />
</td>
<td><textarea id="jwtHeader" cols="50" rows="5" readonly></textarea>
</td>
<td>
<i>dd-ver key identifies the DoorDash JWT version</i>
</td>
</tr>
<tr>
<td><label>Payload</label></td>
<td><textarea id="jwtPayload" cols="50" rows="7" readonly></textarea>
</td>
<td>
</td>
</tr>
<tr>
<td><label>Signature</label></td>
<td><textarea id="jwtSigningSecret" cols="50" rows="5" readonly>
</textarea></td>
<td>
<code>HMACSHA256(base64UrlEncode(header) + "." + base64UrlEncode(payload), Signing Secret)</code>
</td>
</tr>
</table>
<h2>JWT</h2>
<p>
The JWT output is three Base64-URL strings separated by dots.
</p>
<textarea id="jwt" cols="80" rows="10"></textarea>
<h2>More About DoorDash Credentails</h2>
<ul>
<li><a...
JavaScript
const jwtHeaderTemplate = '{"alg": "HS256","typ": "JWT","dd-ver": "DD-JWT-V1"}';
const jwtPayloadTemplate = '{"aud": "doordash","iss": "DEVELOPER_ID","kid": "KEY_ID","iat": "ISSUE_AT","exp": "EXPIRATION"}';
window.onload = setDefaults();
function setDefaults() {
document.getElementById('jwtHeader').value = JSON.stringify(JSON.parse(jwtHeaderTemplate), null, 2);
document.getElementById('jwtPayload').value = JSON.stringify(JSON.parse(jwtPayloadTemplate), null, 2);
}
function base64UrlEncodeString(rawString) {
var noSpaces = rawString.replace(/\s+/g, ''); //remove all whitespace characters
var wordArray = CryptoJS.enc.Utf8.parse(noSpaces);
return base64UrlEncodeWordArray(wordArray);
}
function base64UrlEncodeWordArray(wordArray) {
// Return Base64Encoded String, in Base64URL format:
// * all equal characters (padding) removed
// * all pluses replaced with dashes
// * all slashes replaced with underscores
return CryptoJS.enc.Base64.stringify(wordArray)
.replace(/=+$/, '')
.replace(/\+/g, '-')
.replace(/\//g, '_');
}
function base64UrlDecode(source) {
// Remove characters that were swapped when Base64URL encoded:
// * all dashses replaced with pluses
// * all underscores replaced with slashes
var urlDecoded = source.replace(/-/g, '+')
.replace(/_/g, '/');
// return parsed string as WordArray
return CryptoJS.enc.Base64.parse(urlDecoded);
}
function updateJWT() {
// TODO: Validate the 3 user provided fields are valid
var jwtHeaderEncoded = base64UrlEncodeString(jwtHeaderTemplate); // Base64 encode the Header JSON
var developerId =...