I find cookies, sessions, encryption, OpenID and OIDC all very confusing.  I use the express-openid-connect library to handle our Auth0 integration and for the most part it takes care of all the difficult parts of OAuth, tokens, etc.  Eventually you need to peel back the curtain and adjust things.

tl;dr - the code sample below will do just that.

In my case, I needed to take the appSession cookie that express-openid-connect stored and read the data from it and validate that the cookie data was encrypted with our secrets.

Decoding a token is easy, validation is tricky.

Here's the code I used:

const { JWK, JWE } = require('jose');

const { encryption: deriveKey } = require('express-openid-connect/lib/hkdf');

const jwe = 'eyJhbGciOiJkaXIiLCJlbmMi...';
const key = JWK.asKey(deriveKey(process.env.APP_SECRET));

const encryptOpts = {
  alg: 'dir',
  enc: 'A256GCM',
};
const { cleartext } = JWE.decrypt(jwe, key, {
  complete: true,
  contentEncryptionAlgorithms: [encryptOpts.enc],
  keyManagementAlgorithms: [encryptOpts.alg],
});

console.log(cleartext.toString());

Here's how it works (to my understanding):

  1. Ultimately we have JSON that's encrypted as a string (cleartext.toString() ).
  2. We can get it by using JWE.decrypt.
  3. This takes our original token from iOS, jwe, a key which is based on your app's SECRET and some options.

Then it just works(tm).  For me the difficult part was using JWE and JWK versus jsonwebtoken.


If you like dealing with tokens and encryption and have something to add to this, or would like to work with me, send me an email at eyJhbGciOiJkaXIiLCJlbmMi@davedash.33mail.com