koajs / session

Simple session middleware for koa
MIT License
902 stars 113 forks source link

Add example(s) with external stores? #148

Open danrocha opened 6 years ago

danrocha commented 6 years ago

I would love to get this working for my case, but I find the following part of the readme extremely cryptic:

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):

get(key, maxAge, { rolling }): get session object by key
set(key, sess, maxAge, { rolling, changed }): set session object for key, with a maxAge (in ms)
destroy(key): destroy session for key

Would anyone be kind enough to add an example of the above (especially using redis)? I searched everywhere and it is still a mystery to me how to get it working...

Thanks!! Daniel

dead-horse commented 6 years ago

Maybe you can check out this module as an example.

https://github.com/eggjs/egg-session-redis/blob/master/app.js#L12

danrocha commented 6 years ago

Thanks! Is this going in the right direction?

//  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));
};

Then in my main server file:

// 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}`);

But then how do I access the session and its methods from inside other middlewares? Like in the installFirebaseAuth middleware, I want to finally get/set session values:

...

module.exports = function installFirebaseAuth(app, { rootPgPool }) {
  ...
  const verifyAccessToken = async (ctx, next) => {
      ...
      const accessToken = getAccessToken(ctx);
      const fid = getFID(ctx);

      const getRedisKey = sprintf(process.env.REDIS_STORE_KEY, {
        fid
      });

      // trying to access the session, none work
      console.log('ctx.session', ctx.session);
      console.log('ctx.session.get():', ctx.session.get(getRedisKey));
      console.log('ctx.req.session', ctx.req.session);
      const redisValue = await ctx.req.session.get(getRedisKey);
      ...
   }
}

ctx.session returns {} ctx.session.get() returns ctx.session.get is not a function ctx..req.session returns undefined

Any clues? Thanks!!

Beats0 commented 6 years ago

@danrocha I got the same error with store get, set function finally, I change to use koa-session2 and ioredis maybe you should check out this issues https://github.com/Secbone/koa-session2/issues/39

dead-horse commented 6 years ago

The usage keep the same with cookie base session, you just set value by ctx.session= and get user's session data from ctx.session

dead-horse commented 6 years ago

you can check out the test cases for more examples for how to use:

https://github.com/koajs/session/blob/master/test/store.test.js

kerwin-ly commented 5 years ago

I have the same problem.Any examples?Thanks in advance.

jmitchell38488 commented 5 years ago

Check out below for an in-memory session store: https://github.com/jmitchell38488/koa-session-local

The docs describe an object must have the set, get and destroy functions. It can be defined however you like, as long as the object passed contains those three functions.