Search code examples
node.jssessionrediskoa

Koa Session access store client connection from context


I'm using nodejs with koa as framework, plus koa-session and koa-redis.

import Koa from 'koa';
...
import session from 'koa-session';
import redisStore from 'koa-redis';

const app = new Koa();
app.keys = ["cookieKeys"];
app.use(session({
  maxAge: 5184000000,
  store: redisStore({url: 'redis://localhost:6379'})
}, app));

...
const server = app.listen(1339, () => {
  console.log(`Server listening on port: 1339`);
});

export default server;

Now it's possible to set ctx.session.key = "value"; and get ctx.sessios.key; on redis, because the connection is already estabelished.

How i can access the same redis client used on the koa-session store in other module? Right now I'm creating a new connection:

import { Context, Next, Middleware } from 'koa';
import redis from 'koa-redis';

export default async (ctx: Context, next: Next): Promise<Middleware> => {
    try {
        return await next();
    } catch (err) {
        if (err.status !== 401) {
            throw err;
        }
        const redisClient = await redis({url: 'redis://localhost:6379'}).client;
        const tokenAccess = ctx.cookies.get('tokenAccess', {signed: true});
        const tokenRefresh = ctx.session.tokenRefresh;
        ...

        const isRefreshTokenRevoked = Number.isInteger(await redisClient.zrank('blacklist', tokenRefresh));
        await redisClient.quit();
        if (isRefreshTokenRevoked) {
            throw err;
        }
        ...
    }
}

I found this property inside context ctx.session._sessCtx.store.client. Is correct to use this property for that purpose?


Solution

  • I guess my question jumped a few steps. I re-writed the code with a db.js file and put my redis connection as a singleton:

    import { redisURI } from './config';
    import Redis from 'koa-redis';
    
    export const redisStore = Redis({url: redisURI});
    

    So now I could import this connection and use on index.js and other files:

    import Koa from 'koa';
    ...
    import session from 'koa-session';
    import { redisStore } from './db';
    //import redisStore from 'koa-redis';
    
    const app = new Koa();
    app.keys = ["cookieKeys"];
    app.use(session({
      maxAge: 5184000000,
      store: redisStore
    //store: redisStore({url: 'redis://localhost:6379'})
    }, app));
    
    ...
    const server = app.listen(1339, () => {
      console.log(`Server listening on port: 1339`);
    });
    
    export default server;
    

    Imported on another module:

    import { Context, Next, Middleware } from 'koa';
    import { redisStore } from './db';
    
    export default async (ctx: Context, next: Next): Promise<Middleware> => {
        try {
            return await next();
        } catch (err) {
            if (err.status !== 401) {
                throw err;
            }
            //const redisClient = await redis({url: 'redis://localhost:6379'}).client;
            const tokenAccess = ctx.cookies.get('tokenAccess', {signed: true});
            const tokenRefresh = ctx.session.tokenRefresh;
            ...
            const isRefreshTokenRevoked = Number.isInteger(await redisStore.client.zrank('blacklist', tokenRefresh));
            //const isRefreshTokenRevoked = Number.isInteger(await redisClient.zrank('blacklist', tokenRefresh));
            //await redisClient.quit();
            if (isRefreshTokenRevoked) {
                throw err;
            }
            ...
        }
    }