Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to get token's key kid (key id) using jwks-rsa library

I have some key id that I'll use to verify a token, but it's hardcoded and I don't want it to be so. I'm using the jwks-rsa library to fetch the key from an API endpoint and crack the token open for verification, however the fetch is done in the jwks-rsa client object's option property and because of that I'm unsure how to go about storing the fetched 'kid' value in a variable. It's hard to explain, so I'll show some code.

'use strict'

require('dotenv').config()
const jwt = require('jsonwebtoken')
const jwks = require('jwks-rsa')

const TOKEN_SECRET = 'someweirdtokenstring'

function (request, response, next) {
    const client = jwks({
        jwksUri: process.env.TOKEN_KEY_PUBLIC //this is the API endpoint; responds with a json key
    })
    const kid = 'something' //I don't want to hardcode this
    client.getSigningKey(kid, (error, key) => {
        if (error) throw error
        const signingKey = key.publicKey || key.rsaPublicKey
        const token = TOKEN_SECRET
        if (!token) return response.status(401).send('Access denied')
        try {
            const verified = jwt.verify(token, signingKey, { algorithms: ['RS256'] })
            request.user = verified
            next()
        } catch (error) {
            response.status(400).send({ message: error.message, stack: error.stack })
        }
    })
}

EDIT: It's not super-clean code, but that's not the point here.

like image 230
tomkcey Avatar asked Oct 31 '25 05:10

tomkcey


1 Answers

IMO, you should create the JWT with kid in its header. And simply decode only to read the header.

Here is small snippet,

'use strict'

require('dotenv').config()
const jwt = require('jsonwebtoken')
const jwks = require('jwks-rsa')

const TOKEN_SECRET = 'someweirdtokenstring'

function (request, response, next) {
    const client = jwks({
        jwksUri: process.env.TOKEN_KEY_PUBLIC //this is the API endpoint; responds with a json key
    })
    var decoded = jwt.decode(token, {complete: true});
    const kid = decoded.header.kid
    client.getSigningKey(kid, (error, key) => {
        if (error) throw error
        const signingKey = key.publicKey || key.rsaPublicKey
        const token = TOKEN_SECRET
        if (!token) return response.status(401).send('Access denied')
        try {
            const verified = jwt.verify(token, signingKey, { algorithms: ['RS256'] })
            request.user = verified
            next()
        } catch (error) {
            response.status(400).send({ message: error.message, stack: error.stack })
        }
    })
}
like image 67
Akshay Ijantkar Avatar answered Nov 02 '25 22:11

Akshay Ijantkar



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!