Koa-session 在附加对象后被重置?

Koa-session getting reset after appending object to it?

我有一个控制器可以查找角色,然后用它做一些事情,控制器看起来像:

router.post('/profile/characters', async ctx => {
    try {
        ctx.type = 'json';
        let req = ctx.request;
        if (!('charname' in req.body) || !('charserver' in req.body)) {
            return res.json({
                'success': false,
                error: 'You are missing either the character name, or server'
            });
        }

        let foundChar = await new Promise((res, rej) => {
            bnet.wow.character.aggregate({
                origin: 'us',
                realm: req.body.charserver,
                name: req.body.charname,
                fields: ['items', 'talents']
            }, (err, charData) => {
                if (err) {
                    console.log(err);
                    return rej(err);
                }
                return res(charData);
            });
        });


        if ('status' in foundChar) {
            if (foundChar.status === 'nok') {
                return ctx.body = {
                    'success': false,
                    error: 'There was an error looking up your character, please ensure its a US character, and has been logged into recently'
                };
            }
        }

        foundChar.items.level = foundChar.level;
        foundChar.items.class = foundChar.class;
        foundChar.items.thumbnail = foundChar.thumbnail;
        foundChar.items.name = foundChar.name;

        let {
            items, talents
        } = foundChar;

        let specF = talents.find(x => x.selected) || {};
        let charData = {
            items, specF
        };

        if ('legs' in items || 'hands' in items || 'shoulder' in items) {
            return ctx.body = {
                success: false,
                error: 'To verify it is your own character, please remove your (Shoulders, Hands, and Pants) from your character and try again.'
            };
        }

        ctx.session.foundChar = foundChar; // This line here
        console.log(ctx.session);
        ctx.body = {
            success: true,
            charData
        };

    } catch (err) {
        console.log(err);
        ctx.status = err.status || 500;
        ctx.body = {
            message: err.message
        };
    }
});

当它处理 ctx.session.foundChar = foundChar 时,它似乎出于某种原因重置了我的会话,并且记录会话显示 {} 而不是

{ 
   authenticated: true,
   userid: 1
   ...
}

但是如果我改变 ctx.session.foundChar = "Hello"; < 效果很好。

我不知道会话是否存在数据限制或其他问题,因为这不是 express-session 的问题,但我正在尝试将其全部转换为 Koa,无论如何不确定为什么我的会话正在重置。

foundChar 的例子

{ userid: 1,
  username: 'Blah',
  authenticated: true,
  userLevel: 5,
  hasMainCharacter: true,
  foundChar:
   { lastModified: 1453702285000,
     name: 'Blah',
     realm: 'Mal\'Ganis',
     battlegroup: 'Vindication',
     class: 4,
     race: 5,
     gender: 0,
     level: 100,
     achievementPoints: 6335,
     thumbnail: 'internal-record-3684/9/119507209-avatar.jpg',
     calcClass: 'c',
     faction: 1,
     items:
      { averageItemLevel: 714,
        averageItemLevelEquipped: 573,
        head: [Object],
        neck: [Object],
        back: [Object],
        chest: [Object],
        wrist: [Object],
        waist: [Object],
        feet: [Object],
        finger1: [Object],
        finger2: [Object],
        trinket1: [Object],
        trinket2: [Object],
        mainHand: [Object],
        offHand: [Object],
        level: 100,
        class: 4,
        thumbnail: 'internal-record-3684/9/119507209-avatar.jpg',
        name: 'Blah' },
     talents: [ [Object], [Object] ],
     totalHonorableKills: 258 } }

所以这个记录正确,但是在刷新页面后我不再通过身份验证并且 ctx.session{}

问题

你的问题是,因为 koajs/session 用法是

Simple cookie-based session middleware for Koa.

这意味着当 ctx.session 在每个请求之后被序列化为 json 并存储在 cookie 中,并且在每个请求之前被反序列化。

不幸的是,cookie 的大小有限,当您尝试使用 ctx.session.foundChar = foundChar 将大对象存储到其中时,它超过了 cookie 的最大大小并导致会话 cookie 损坏。

出于同样的原因,ctx.session.foundChar = "Hello" 有效,因为 json 大小不超过最大 cookie 大小。

解决方案

为会话使用基于数据库的存储,不错的选择可能是 koa-session-storage

查找 session storage layer 配置选项

The store configuration option specifies where the session data is stored. If omitted or set to "cookie" then session data will be stored in the cookie itself.

If you wish to store session data elsewhere (e.g. in Mongo, Redis, etc.) then you must set this to an object which exposes the following API:

  • load(sid) - load session data for given session id * sid - {String} session identifier. * returns a Promise, Thunk or generator which returns a JSON string of the session object data.

  • save(sid, data) - save session data for given session id * sid - {String} session identifier. * data - _{String} session data converted to JSON string. * returns a Promise, Thunk or generator which returns once data is saved.

  • remove(sid) - remove session data for given session id * sid - {String} session identifier. * returns a Promise, Thunk or generator which returns once removal is complete.

The following storage layers are currently available: