自动登录越权
背景
小程序原生跳转到webview的H5页面时,需要打通用户登录;此时需要在跳转的URL上带上临时token,通过临时token换取登录cookie。
实现的方案为通过Node服务的拦截器,自动拦截小程序环境中的H5页面请求,自动设置上cookie。
问题&原因
自动登录相关的逻辑封装在AutoLogin类中,如下所示
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41
|
class AutoLogin { constructor () { this.ctx = null }
init (ctx) { this.ctx = ctx return this }
trackRule () {
}
async autoLogin () {
}
async autoLogout () {
} } }
module.exports = new AutoLogin()
|
核心原因在于this.ctx = ctx这一行,这行代码意味着在内存中持有了koa的ctx对象,当并发场景,会造成第一个请求链路还未完结时,ctx被替换为第二个请求的上下文对象了,从而造成header中的cookie信息不对,权限错乱。
类型异常
问题&原因
问题代码如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
| Object.entries(config.proxy).map(([path, target]) => { let { url, login, intercept, extParams } = this.getProxyParams(target) this.addRouter({ routerPath: `${routerRoot}${path}`, target: url, callback: async ctx => { // 支持extParams为function类型,传入ctx方便从request中获取数据 extParams = Object.assign({}, typeof (extParams) === 'function' ? extParams(ctx) : extParams) // 登录校验 if (login) {
} // 接口透传 await proxy.launch({ url, reqParams }, ctx) } }) })
|
问题在于这一行代码extParams = Object.assign({}, typeof (extParams) === 'function' ? extParams(ctx) : extParams)
第一次请求的时候extParams为function类型,正常运行;第二次进来由于extParams已经变为了Object类型了,所以这段代码当第二个人请求进来时,永远都是运行的false逻辑,也就是第一个人ctx中的内容。
最后
- 在Node服务中,切忌保存上下文对象,尽量不要持有跟用户相关的非全局信息
- 缺少TS的场景下,注意JS的类型
留言
欢迎交流想法。留言会通过 GitHub Issues 保存,首次使用需要登录 GitHub。