【问题标题】:koa, sessions, redis: how to make it work?koa,会话,redis:如何使其工作?
【发布时间】:2019-03-26 21:01:31
【问题描述】:

我正在尝试使用 koa、koa-session、koa-redis 通过服务器端会话实现 Firebase 身份验证。

我就是无法理解。在阅读 koa-session 自述文件时,这对我来说特别神秘(link):

您可以将会话内容存储在外部存储(Redis、MongoDB 或其他 DB)中,方法是使用三个方法(这些方法必须是异步函数)传递 options.store:

get(key, maxAge, { rolling }): 按键获取会话对象

set(key, sess, maxAge, { rolling, changed }): 为key设置会话对象,maxAge(毫秒)

destroy(key): 销毁密钥会话

四处询问后,我这样做了:

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

然后在我的主要server.js 文件中:

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

但是我如何从其他中间件中访问会话及其方法呢?就像在 installFirebaseAuth 中间件中一样,我想最终获取/设置会话值:

// installFirebaseAuth.js
...

module.exports = function installFirebaseAuth(app) {
  ...
  const verifyAccessToken = async (ctx, next) => {
      ...

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

ctx.session 返回{}

ctx.session.get() 返回ctx.session.get is not a function

ctx.req.session 返回undefined

有什么线索吗? 谢谢!!

【问题讨论】:

  • 我知道它有点旧,但您找到解决方案了吗?
  • 不是真的,我前段时间放弃了 Koa....
  • 与 express 相比,他们的文档是一场灾难。无论如何,谢谢你的回答。

标签: session redis koa


【解决方案1】:

对我有用,希望对你有帮助

const Koa = require('koa')
const app = new Koa()

const Router = require('koa-router')
const router = new Router()

const static = require('koa-static')
const session = require('koa-session')
// const ioredis = require('ioredis')
// const redisStore = new ioredis()
const redisStore = require('koa-redis')
const bodyparser = require('koa-bodyparser')

app.use(static('.'))
app.use(bodyparser())
app.keys = ['ohkeydoekey']
app.use(session({
  key: 'yokiijay:sess',
  maxAge: 1000*20,
  store: redisStore()
}, app))

app.use(router.routes(), router.allowedMethods())

router.post('/login', async ctx=>{
  const {username} = ctx.request.body
  if(username == 'yokiijay'){
    ctx.session.user = username
    const count = ctx.session.count || 0
    ctx.session.code = count
    ctx.body = `wellcome ${username} logged in`
  }else {
    ctx.body = `sorry, you can't login`
  }
})

router.get('/iflogin', async ctx=>{
  if(ctx.session.user){
    ctx.body = ctx.session
  }else {
    ctx.body = 'you need login'
  }
})

app.listen(3000, ()=>{
  console.log( 'app running' )
})

【讨论】:

  • 这实际上是行不通的。如果您查看 redis 存储的内容,您会注意到它没有创建任何会话。到今天为止,包 koa-session 和 koa-redis 不兼容。 koa-session 只是默认为内存存储实现。
猜你喜欢
  • 2023-03-15
  • 2014-10-19
  • 2016-06-20
  • 2011-02-26
  • 2015-09-09
  • 1970-01-01
  • 2016-11-20
相关资源
最近更新 更多