коа, сессии, редис: как заставить работать? - PullRequest
0 голосов
/ 22 октября 2018

Я пытаюсь реализовать аутентификацию Firebase с сеансами на стороне сервера, используя koa, koa-session, koa-redis.

Я просто не могу этого понять.При чтении файла readme для koa-сеанса это особенно загадочно для меня ( link ):

Вы можете хранить содержимое сеанса во внешних хранилищах (Redis, MongoDB или других БД)путем передачи options.store тремя методами (это должны быть асинхронные функции):

get (key, maxAge, {roll}): получить объект сеанса по ключу

set (key, sess, maxAge, {Rolling, Change}): установить объект сеанса для ключа, с maxAge (в мс)

destroy (ключ): уничтожить сеанс для ключа

После опроса вокругЯ сделал это:

//  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

Есть какие-нибудь подсказки?Спасибо !!

1 Ответ

0 голосов
/ 16 августа 2019

Это работает в моем случае, надеюсь, это поможет вам

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' )
})
...