Kevin F.
Kevin F.

Reputation: 140

Generating JTI claim for JWT in javascript

I am asking this since a colleague has been stuck on this for a few days now. The problem is, he's trying to use the JTI claim in his JWT but he can't seem to figure out how to properly generate it. Nowhere can we find a clear and straight to the point explanation on how to generate and format the JTI, if that is necessary at all. We would appreciate it if anyone could clear things up for us.

UPDATE: This is an example of the code used

var randomNumber1 = Math.floor(Math.random() * Math.floor(254));
var randomText = Math.random().toString(36).substr(2, 12);
var randomNumber2 = Math.floor(Math.random() * Math.floor(81458));

var oHeader = {alg: 'HS256', cty: 'text/plain'};
var oPayload = {};
oPayload.publicKey = "myPublicKey";
oPayload.schema = "mySchema";
oPayload.baseUrl = "www.example.org";
oPayload.exp = (new Date().getTime() / 1000|0)  + 5 * 60;
oPayload.iss = "myIssuer";
oPayload.domain = "myDomain";
oPayload.jti = randomNumber1 + "-" + randomText + "-" + (new 
Date().getTime() / 1000|0)  + 5 * 60;
oPayload.iat = new Date().getTime() / 1000|0;

var hash = CryptoJS.MD5("Message", (new Date().getTime() / 1000|0)  
+ 5 * 60);
console.log(hash);

If more information is required, please do ask.

Thanks in advance.

Upvotes: 7

Views: 10922

Answers (1)

Avius
Avius

Reputation: 6284

The other answer linked to by Mark M. contains an excerpt from the JWT spec, which describes the requirements for the jti claim. Basically, it works as an identifier, so it must be unique in whatever scope it is used. What that means depends on the application.

It is not important for this claim to be hard-to-guess since every time you create a new one, you will resign and regenerate the whole token. So you could probably even use a simple counter, provided you can ensure that the same counter will never be used twice on different tokens, even by accident.

In most cases some already established solution for generating (semi-)random unique IDs would probably be your best bet. Some suggestions:

  1. To be sure you could go with UUIDs. There is a popular npm package for them.
  2. The implementation of this package is apparently based on Node's native crypto.randomBytes(), which itself is an option.
  3. If you use Mongo, perhaps Mongo's ObjectId would work.
  4. Using Math.random() (and, possibly, dates) as your colleague did, could also be an option.
  5. As mentioned, a counter might work in certain scenarios.

Each one of these provides for a different degree of randomness/uniqueness while putting different loads on the CPU and yielding IDs of different sizes/lengths. You are the one to decide which solution is the most appropriate. For my use case I will be choosing randomBytes, as I find it sufficient for my needs:

How random is crypto#randomBytes?

Are the odds of a cryptographically secure random number generator generating the same uuid small enough that you do not need to check for uniqueness?

It can be expensive performance-wise, but I don't need too many bytes and it has a non-blocking mode, which uses libuv's threadpool.

Upvotes: 5

Related Questions