Add crypto-js and use crypto-js/aes to encode JSON Web Tokens after they have been signed, and to decode them before they are verified.
The initial implementation will use a symmetric algorithm, and the jwtSecret will be used to encrypt and to sign the token. This allows for a simple and reasonably secure implementation that can be expanded later to support other authentication mechanisms, like asymmetric algorithms, in a backwards compatible way.
The only "private" information currently "exposed" to a client is the database user ID (e.g. an int if using an SQL DB or an Object ID if using MongoDB). It can be desirable not to expose this, though it's rarely considered actually "secret".
The RefreshToken and AccessToken for the service the user used belong to the user, and it's okay for them to know them.
Only the server, the browser and the user can read this data.
The cookie is HTTP only
Currently, the JWT is signed but not encrypted.
It should be encrypted to avoid inadvertently exposing data, especially if we add functions to allow people to customise what is stored in the JWT.
It would be sensible to move to the methods for setting (encrypting + signing) and getting (decrypting + verifying) the JWT into functions like set() and get() methods, and to allow those functions to be defined as options server side.
Example method signatures:
async setJWT({ secret, user, provider, options })async getJWT({ secret, user, provider, options })The current jwt: true and jwtSecrets option could change to be an object.
e.g.
jwt: {
enabled: true,
secret: '',
set: async ({ secret, token }) => { return encryptedToken },
get: async ({ secret, encryptedToken }) => { return token },
}
The token would be populated with the current contents by default, but people could add whatever they need to it, and choose whatever encryption and description system they want.
If we are changing this, it seems sensible to similarly change the sessionMaxAge and sessionUpdateAge options too, and to add a get method to support returning a custom session object when using a database based session.
session: {
maxAge: 30*24*60*60*1000,
updateAge: 24*60*60*1000,
get: async ({ user, session }) => { return customSessionObject }
}
This would keep the behaviour similar.
@LoriKarikari @ndom91 ^ This is what I'm thinking of doing tomorrow.
It will mean one last breaking change to the config format before release, but will make it easier to make changes (adding/removing options to jwt and session options) without making breaking changes again.
Most helpful comment
@LoriKarikari @ndom91 ^ This is what I'm thinking of doing tomorrow.
It will mean one last breaking change to the config format before release, but will make it easier to make changes (adding/removing options to
jwtandsessionoptions) without making breaking changes again.