我有一个查找角色的控制器,然后用它做一些东西,控制器看起来像:
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
为{}
答案 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 或删除完成后返回的生成器。目前有以下存储层:
- MongoDB - koa-session-mongo