Koa-сессия сбрасывается после добавления к ней объекта?

У меня есть контроллер, который ищет персонажа, а затем что-то с ним делает, контроллер выглядит так:

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 становится {}


person Datsik    schedule 28.01.2016    source источник
comment
Сеанс хранится в файле cookie? Возможно, вы превысите максимальную длину файла cookie после сериализации сеанса в строку.   -  person mikefrey    schedule 30.01.2016
comment
почему вы сохраняете весь объект в сеансе? сеанс должен быть как можно меньше. просто сохраните идентификатор персонажа, а затем получите идентификатор из базы данных при каждом запросе   -  person Jonathan Ong    schedule 07.02.2016
comment
@mikefrey, вы правы, это так, я ответил на вопрос, включая этот пункт.   -  person gevorg    schedule 26.06.2016
comment
@JonathanOng Я согласен, я указал вариант в своем ответе.   -  person gevorg    schedule 26.06.2016


Ответы (1)


Проблема

Ваша проблема в том, что из-за использования koajs/session это

Простое промежуточное программное обеспечение сеанса на основе файлов cookie для Koa.

Это означает, что ctx.session сериализуется в json и сохраняется в файле cookie после каждого запроса и десериализуется перед каждым запросом.

К сожалению, файл cookie имеет ограниченный размер, и когда вы пытаетесь сохранить в нем большой объект с помощью ctx.session.foundChar = foundChar, он превышает максимальный размер файла cookie и приводит к повреждению файла cookie сеанса.

По той же причине работает ctx.session.foundChar = "Hello", потому что размер json не превышает максимальный размер файла cookie.

Решение

Используйте хранилище на основе БД для сеанса, хорошим выбором для него может быть koa-session-storage.

Посмотрите уровень хранения сеансов для параметров конфигурации.

Параметр конфигурации store указывает, где хранятся данные сеанса. Если опущено или установлено значение "cookie", данные сеанса будут храниться в самом файле cookie.

Если вы хотите хранить данные сеанса в другом месте (например, в Mongo, Redis и т. д.), вы должны установить это как объект, который предоставляет следующий API:

  • load(sid) — загрузить данные сеанса для заданного идентификатора сеанса * sid — идентификатор сеанса {String}. * возвращает Promise, Thunk или генератор, который возвращает строку JSON данных объекта сеанса.

  • save(sid, data) — сохранить данные сеанса для заданного идентификатора сеанса * sid — идентификатор сеанса {String}. * data - данные сеанса _{String} преобразованы в строку JSON. * возвращает Promise, Thunk или генератор, который возвращается после сохранения данных.

  • remove(sid) — удалить данные сеанса для заданного идентификатора сеанса * sid — идентификатор сеанса {String}. * возвращает Promise, Thunk или генератор, который возвращается после завершения удаления.

В настоящее время доступны следующие уровни хранения:

person gevorg    schedule 26.06.2016