Search code examples
node.jsexpressexpress-session

express-session - is it possible to change the secret while the node app is running?


Usually the secret is hard-coded in node apps which use express-session, for example -

const session = require("express-session")
let RedisStore = require("connect-redis")(session)
const { createClient } = require("redis")
let redisClient = createClient({ legacyMode: true })
redisClient.connect().catch(console.error)
app.use(
  session({
    store: new RedisStore({ client: redisClient }),
    saveUninitialized: false,
    secret: "keyboard cat",
    resave: false,
  })
)

Obviously I can change this secret keyboard cat by editing the source and restarting the node script. It is possible to change it while the app is still running?


Solution

  • Per the guidelines here, the session secret can be changed by passing an array of secrets instead of the single secret and you can then secrets.unshift(newSecret) a new secret into the first spot in the array while continuing to accept cookies that have used the other secrets in the array.

    So, in your code, you would do this:

    const session = require("express-session");
    
    let RedisStore = require("connect-redis")(session);
    const { createClient } = require("redis");
    let redisClient = createClient({ legacyMode: true });
    redisClient.connect().catch(console.error);
    
    const secrets = ["keyboard cat"];
    
    app.use(
      session({
        store: new RedisStore({ client: redisClient }),
        saveUninitialized: false,
        secret: secrets,
        resave: false,
      })
    );
    

    Then, sometime later in your code, you can update the current secret being used like this:

    secrets.unshift("my new secret");
    

    The session middleware will always use the secret at the start of the array for new sessions, but will continue to accept cookies that use the other secrets in the array.

    My motivation is that I put most of my code on github and I prefer not to hard-code any passwords or secrets.

    If this is your motivation, then usually, you make the session secret part of some configuration/deployment file that is NOT checked into github and is managed separately. This is the same type of config file you would put database passwords and other credentials needed for your server. That way, when your server starts up, it gets the credentials/secrets it needs from a local configuration file that is not stored in github.

    Then, you also don't have to try to change a running session middleware secret on the fly either.


    Now that you mention Heroku, here are the techniques that Heroku mentions for managing configuration variables:

    https://devcenter.heroku.com/articles/config-vars