title: koa, sessions, redis: how to make it work?
body: <p>I am trying to implement Firebase authentication with server-side sessions using koa, koa-session, koa-redis.</p>
  <p>I just can't grasp it. When reading the koa-session readme, this is particularly cryptic to me (<a href="https://github.com/koajs/session#external-session-stores" rel="nofollow noreferrer">link</a>):</p>
  <blockquote>
  <p>You can store the session content in external stores (Redis, MongoDB or other DBs) by passing options.store with three methods (these need to be async functions):</p>
  <p>get(key, maxAge, { rolling }): get session object by key</p>
  <p>set(key, sess, maxAge, { rolling, changed }): set session object for key, with a maxAge (in ms)</p>
  <p>destroy(key): destroy session for key</p>
  </blockquote>
  <p>After asking around, I did this:</p>
  <pre class="lang-js prettyprint-override"><code>//  middleware/installSession.js
  const session = require('koa-session');
  const RedisStore = require('koa-redis');
  const ONE_DAY = 1000 * 60 * 60 * 24;
  
  module.exports = function installSession(app) {
    app.keys = [process.env.SECRET];
  
    app.use(session({
      store: new RedisStore({
        url: process.env.REDIS_URL,
        key: process.env.REDIS_STORE_KEY,
        async get(key) {
          const res = await redis.get(key);
          if (!res) return null;
          return JSON.parse(res);
        },
  
        async set(key, value, maxAge) {
          maxAge = typeof maxAge === 'number' ? maxAge : ONE_DAY;
          value = JSON.stringify(value);
          await redis.set(key, value, 'PX', maxAge);
        },
  
        async destroy(key) {
          await redis.del(key);
        },
      })
    }, app));
  };
  </code></pre>
  <p>Then in my main <code>server.js</code> file:</p>
  <pre class="lang-js prettyprint-override"><code>// server.js
  ...
  const middleware = require('./middleware');
  
  const app = new Koa();
  const server = http.createServer(app.callback());
  
  // session middleware
  middleware.installSession(app);
  
  // other middleware, which also get app as a parameter
  middleware.installFirebaseAuth(app);
  ...
  const PORT = parseInt(process.env.PORT, 10) || 3000;
  server.listen(PORT);
  console.log(`Listening on port ${PORT}`);
  </code></pre>
  <p>But then how do I access the session and its methods from inside other middlewares? Like in the <code>installFirebaseAuth</code> middleware, I want to finally get/set session values:</p>
  <pre class="lang-js prettyprint-override"><code>// installFirebaseAuth.js
  ...
  
  module.exports = function installFirebaseAuth(app) {
    ...
    const verifyAccessToken = async (ctx, next) =&gt; {
        ...
  
        // trying to access the session, none work
        console.log('ctx.session', ctx.session);
        console.log('ctx.session.get():'
        ctx.session.get(process.env.REDIS_STORE_KEY));
        console.log('ctx.req.session', ctx.req.session);
        const redisValue = await ctx.req.session.get(process.env.REDIS_STORE_KEY);
        ...
     }
  }
  </code></pre>
  <p><code>ctx.session</code> returns <code>{}</code></p>
  <p><code>ctx.session.get()</code> returns <code>ctx.session.get is not a function</code></p>
  <p><code>ctx.req.session</code> returns <code>undefined</code></p>
  <p>Any clues?
  Thanks!!</p>