Summary
I'll be covering the usage of the RFC 7523 authorization grant type in this post. I'll create a server-side implementation as a Google Cloud Function and a simple client in Node.js.
Architecture
The implementation consists of a Google Cloud Function that is triggered on an HTTP POST request. The request has a form-urlencoded body consisting of the grant_type parameter and an assertion with the JSON web token (JWT) - per the RFC. The response is a JSON object consisting of the token type, bearer token, and the unencoded version of the original JWT received. That last item isn't required, but I included it to aid in troubleshooting.
Server-side Snippet
As discussed, the server is implemented as a GCF. For a Node implementation, that consists of an Express server. The express-jwt middleware is used to implement the JWT handling.
app.use(expressJwt({
secret: sharedKey,
issuer: issuer,
audience: audience,
algorithms: ['HS256', 'HS384', 'HS512'],
requestProperty: 'token',
getToken: (req) => {
return req.body.assertion;
}
}));
app.post('/rfc7523', (req, res) => {
if (req.token) {
console.log(`Received token: ${JSON.stringify(req.token)}`);
const alg = 'HS512'
const payload = {
"iss": 'oauth issuer',
"sub": 'oauth authority',
"aud": 'm2mclient',
"exp": Math.round(Date.now()/1000 + 3) //3 second expiration
};
const accessToken = jwt.sign(payload, privateKey, {algorithm: alg});
res.status(200)
.json({
token_type: 'bearer',
rec_token: req.token,
access_token: accessToken
});
}
else {
res.status(400).json({error: 'no token found'});
}
});
Client-side Snippet
(async () => {
const payload = {
"iss": issuer,
"sub": subject,
"aud": audience,
"exp": Math.round(Date.now()/1000 + 3) //3 second expiration
};
const alg = 'HS512'
const token = jwt.sign(payload, sharedKey, {algorithm: alg});
const authGrant = encodeURI('urn:ietf:params:oauth:grant-type:jwt-bearer');
const response = await fetch(url, {
method: 'POST',
headers: {'Content-Type': 'application/x-www-form-urlencoded'},
body: `grant_type=${authGrant}&assertion=${token}`
});
const json = await response.json();
console.log(`Results: ${JSON.stringify(json, null, 4)}`);
})();
Results
Results: {
...
"access_token": "eyJhbGciOiJIUzUxMiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJvYXV0aCBpc3 - abbreviated"
}
Source
Copyright ©1993-2024 Joey E Whelan, All rights reserved.

