为什么要获取?
@dead-horse 想要在缓存中存取,进行对单端登陆的验证!
不需要通过key获取,直接在request 中获取session就可以了呀,会话未结果可以直接从session拿
如果是基于 ip 做限制,将 ip 写到 session 中即可,自行做校验。如果一定要获取到 key,可以通过 opts. genid 参数来自行控制 session id 的生成方式。文档地址:https://github.com/koajs/session
@dead-horse 当使用CAS做单点登出的时候,是需要获取session id的。原因:
如果有A,B两个子系统。它们都处于登录状态,当B系统退出登录,A系统也需要自动退出,这样A系统之前存储在redis中的session就需要手动进行销毁。现在因为没有sessionId,无法销毁session,导致A系统刷新页面,仍然处于登录状态。
提到的配置opts.genid,我在config.default.js中:
config.session = { genid: () => return uuid;}
但存在的问题是,config.default.js中无法获取ctx,如何将该id传到middleware中进行使用呢?
我看了koa-session源码,不知道作者出于什么样的考虑,没有在context.js的create方法中将生成的externalKey挂载到session上
我现在的解决方案是:
1、修改源码,在create方法中,this.session.id = this.externalKey;
2、从cookie中获取,this.session.id = ctx.cookies.get('EGG_SESS', ctx.sessionOptions);
这样做会有什么潜在的问题吗?
我看egg-session-redis中有这样的代码(或扩展egg-session):
app.sessionStore = {
async get(key) {
const res = await redis.get(key);
if (!res) return null;
return JSON.parse(res);
},
async set(key, value, maxAge) {
maxAge = typeof maxAge === 'number' ? maxAge : ONE_DAY;
value = JSON.stringify(value);
await redis.set(key, value, 'PX', maxAge);
},
async destroy(key) {
await redis.del(key);
},
};
app.sessionStore.get()进行key的可控性和规则性,而不是自动生成的session id。如果开启了session-redis,那就意味着session不会存在本地,也就是ctx.session.user='hello'这样原本存在cookie中也会存至redis,对吧?
逻辑是这样的:
如果没有开启redis,即session没有配置store的情况下,egg-session会对session中的内容进行加密,然后以EGG_SESS(默认的)为key,将其存储在cookie里发送到浏览器。下次请求,再将cookie中的内容进行解密,恢复到服务器的session里。
如果开启redis,即session配置了store,egg-session会自动将session内容和配置选项(maxAge,expire等)存入redis中,期间会判断session是否配置了genid函数,如果没有配置,会生成一个随机的extenalKey作为session的key。接下来会将EGG_SESS作为key,externalKey作为value,存入cookie中,响应到前端。
app.sessionStore 只是对redis存取,销毁做的封装,跟sessionId没有关系。
总结:
如果session没有配置store选项,cookie中存的是session加密后的内容。如果session配置了store,cookie中存的是redis中的key(即sessionId)。
不是吧,随机生成的externalKey,和cookie中存储的externalKey,我根本连不起来啊,你是id设置成cookie中的值了吧,不是自动生成的吧?
cookie中的externalKey是随机生成的key加密过的,你需要ctx.cookies.get('EGG_SESS', ctx.sessionOptions);
进行解密
哇,真的耶,多谢大佬指点~
还有一个小问题,如果公司项目的要求redis的key值规范,例如NGCS_SERVICEREQ:20161215001,怎么解决比较好呢?后面数字自定义,:前面的根据项目定义。
config.defaut.js中配置session:
config.session = {
genid: () => {
return 'NGCS_SERVICEREQ:' + 数字;
}
}
this.ctx.session._sessCtx.externalKey
不知是不是各位想要的。。。
this.ctx.session._sessCtx.externalKey
不知是不是各位想要的。。。
竟然藏这么深
Most helpful comment
this.ctx.session._sessCtx.externalKey
不知是不是各位想要的。。。