Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Koa-session getting reset after appending object to it?

I have a controller which looks up a character, and then does some stuff with it, the controller looks like:

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

When it processes ctx.session.foundChar = foundChar it seems to reset my session for some reason, and logging the session shows {} instead of

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

But if I change ctx.session.foundChar = "Hello"; < Works just fine.

I don't know if there is a data limit or something to the session or what as this wasn't an issue with express-session but I'm trying to convert it all over to Koa, anyways not sure why my session is getting reset.

Example of what foundChar looks like

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

So this logs properly, but then after refreshing the page im no longer authenticated and ctx.session is {}

like image 702
Datsik Avatar asked Sep 25 '22 13:09

Datsik


1 Answers

Problem

Your problem is, because of koajs/session usage which is

Simple cookie-based session middleware for Koa.

Which means when ctx.session is being serialized into json and stored in cookie after each request and is being deserialized before each request.

Unfortunately cookie has limited size and when you try to store big object into it with ctx.session.foundChar = foundChar it exceeds maximum cookie size and results currupted session cookie.

For same reason ctx.session.foundChar = "Hello" works, because json size does not exceed max cookie size.

Solution

Use db based storage for session, good choice for it could be koa-session-storage.

Look session storage layer for configuration options

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:

  • MongoDB - koa-session-mongo
like image 133
gevorg Avatar answered Sep 28 '22 05:09

gevorg