在附加对象后,Koa会话被重置?

时间:2016-01-28 00:49:58

标签: javascript node.js koa koa2 koa-session

我有一个查找角色的控制器,然后用它做一些东西,控制器看起来像:

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{}

1 个答案:

答案 0 :(得分:4)

问题

您的问题是,因为koajs/session使用

  

简单的基于cookie的会话中间件,适用于Koa。

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

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

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

解决方案

使用基于数据库的存储进行会话,可以选择koa-session-storage

查看session storage layer了解配置选项

  

store配置选项指定会话数据的位置   存储。如果省略或设置为"cookie",那么会话数据将是   存储在cookie本身。

     

如果您希望在其他地方存储会话数据(例如,在Mongo,Redis,   然后你必须将它设置为暴露以下内容的对象   API:

     
      
  • 加载(sid) - 加载给定会话ID * sid的会话数据 -    {String} 会话标识符。 *返回Promise,Thunk或生成器,它返回会话对象数据的JSON字符串。

  •   
  • 保存(sid,数据) - 保存给定会话ID的会话数据*   sid - {String} 会话标识符。 * data - _ {String}会话   数据转换为JSON字符串。 *返回Promise,Thunk或   保存数据后返回的生成器。

  •   
  • 删除(sid) - 删除给定会话ID *的会话数据   sid - {String} 会话标识符。 *返回Promise,Thunk   或删除完成后返回的生成器。

  •   
     

目前有以下存储层: