开发环境自动获取cookie

815 阅读4分钟


1.背景

1.1 权限校验流程

车载屏系统通过node中间层注入cookie、并通过cookie进行权限校验。

测试环境注入cookie的domain为czp-test.intra.xiaojukeji.com,而我们本地环境通过webpack.devserver设置的host为 local.intra.xiaojukeji.com

由于浏览器的同源策略,所以本地环境是不可以共享测试环境cookie的。

车载屏登录校验流程图:

[

](wiki.intra.xiaojukeji.com/plugins/gli…

](wiki.intra.xiaojukeji.com/plugins/gli…)

[

](wiki.intra.xiaojukeji.com/pages/viewp…)

2.2 本地开发环境之前获取cookie的方式

  1. 登录测试环境,在控制台输入 copy(document.cookie) 复制测试环境cookie

  2. 返回开发环境,打开控制台,输入双引号,在双引号内粘贴刚刚复制的cookie,在cookie后面输入如下代码 .split('; ').forEach(item => document.cookie = item)
    效果如下:

    "language=zh_CN; SSO_AS_VEHICLE_TICKET=df35aa0fbe67caa3775c21c247d819f20002718000; SSO_AS_VEHICLE_UID=lihongxiang; promise-ticket=df35aa0fbe67caa3775c21c247d819f20002718000; MISP_SUB_TICKET=df35aa0fbe67caa3775c21c247d819f20002718000; MISP_SUB_USER_NAME=lihongxiang; SSO_AS_VEHICLE_TICKET_DEV=df35aa0fbe67caa3775c21c247d819f20002718000; SSO_AS_VEHICLE_UID_DEV=lihongxiang; promise-ticket_DEV=df35aa0fbe67caa3775c21c247d819f20002718000; MISP_SUB_TICKET_DEV=df35aa0fbe67caa3775c21c247d819f20002718000; MISP_SUB_USER_NAME_DEV=lihongxiang; __hash__wa=20211217-2718-lihongxiang-40323659-36f8-434a-8c59-fbbf712e67aa; __hash__cache=40323659-36f8-434a-8c59-fbbf712e67aa; user-fingerprint-water-mark=20211217-2718-lihongxiang-40323659-36f8-434a-8c59-fbbf712e67aa".split('; ').forEach(item => document.cookie = item)

  3. 重新刷新开发环境地址,进入正常开发

2. 解决方案

2.1 前端项目配置

既然是cookie的同源限制,首先需要将开发环境与预测试环境的一二级域名设置为相同域名。

开发环境webpack配置:

devServer: {

host: 'local.intra.xiaojukeji.com',

port: '8777',

hot: true, // 开启热更新,提高开发效率

},

只是把host改成了local.intra.xiaojukeji.com ,然后修改host文件,添加一行 127.0.0.1 local.intra.xiaojukeji.com

2.2 node项目修改

所以在node服务设置cookie的时候,设置下domain= .xiaojukeji.com ,开发环境就可以访问测试环境的cookie了。

确实是这样,但是预发环境、正式环境的一二级域名也是 .intra.xiaojukeji.com ,这样就影响了正常的预发、正式环境访问了,所以这个方案不可以。

如何能做到开发环境共享cookie,又能不影响正式环境?

共享cookie只能设置domain = .xiaojukeji.com

不影响正式环境,可以给开发环境设置单独的cookie:key值带有dev标记,value还是正常的value。然后前端本地环境获取到带有dev标记的cookie,通过slice,将 key值的dev标记剔除,解析成正确的cookie,就可以获取真实的cookie了。

node项目cookie设置代码:(注意看注释)

node

class LoginController extends Controller {

async index(ctx: Context): Promise<void> {

try {

const { code, jumpto } = ctx.query

const res = await ctx.service.ssoLogin.index(code)

if (res.errno !== 0) {

ctx.body = res

return

}

const { ticket, username } = res.data

ctx.cookies.set(``'SSO_AS_VEHICLE_TICKET'``, ticket, {

maxAge: 24 * 3600 * 1000,

httpOnly: false``,

sameSite: 'None'``,

signed: false``,

})

ctx.cookies.set(``'SSO_AS_VEHICLE_UID'``, username, {

maxAge: 24 * 3600 * 1000,

httpOnly: false``,

sameSite: 'None'``,

signed: false``,

})

ctx.cookies.set(``'promise-ticket'``, ticket, {

maxAge: 24 * 3600 * 1000,

httpOnly: false``,

sameSite: 'None'``,

signed: false``,

})

ctx.cookies.set(``'MISP_SUB_TICKET'``, ticket, {

maxAge: 24 * 3600 * 1000,

httpOnly: false``,

sameSite: 'None'``,

signed: false``,

})

ctx.cookies.set(``'MISP_SUB_USER_NAME'``, username, {

maxAge: 24 * 3600 * 1000,

httpOnly: false``,

sameSite: 'None'``,

signed: false``,

})

// 以下cookie是专门为开发环境准备的,开发环境通过解析key,则可以还原测试环境真正的cookie

if``(ctx.app.config.env === 'stable'``) {

ctx.cookies.set(``'SSO_AS_VEHICLE_TICKET_DEV'``, ticket, {

maxAge: 24 * 3600 * 1000,

httpOnly: false``,

sameSite: 'None'``,

signed: false``,

domain: '.xiaojukeji.com'

})

ctx.cookies.set(``'SSO_AS_VEHICLE_UID_DEV'``, username, {

maxAge: 24 * 3600 * 1000,

httpOnly: false``,

sameSite: 'None'``,

signed: false``,

domain: '.xiaojukeji.com'

})

ctx.cookies.set(``'promise-ticket_DEV'``, ticket, {

maxAge: 24 * 3600 * 1000,

httpOnly: false``,

sameSite: 'None'``,

signed: false``,

domain: '.xiaojukeji.com'

})

ctx.cookies.set(``'MISP_SUB_TICKET_DEV'``, ticket, {

maxAge: 24 * 3600 * 1000,

httpOnly: false``,

sameSite: 'None'``,

signed: false``,

domain: '.xiaojukeji.com'

})

ctx.cookies.set(``'MISP_SUB_USER_NAME_DEV'``, username, {

maxAge: 24 * 3600 * 1000,

httpOnly: false``,

sameSite: 'None'``,

signed: false``,

domain: '.xiaojukeji.com'

})

}

ctx.redirect(jumpto)

} catch (error) {

this``.logger.error(``'sso_login ERROR:'``, error)

ctx.status = error.response.status || 500

ctx.body = error

}

}

}

export default LoginController

mis系统解析cookie

在APP组件中

beforeCreate() {

// 如果是开发环境,cookie获取通过auth-server单独为开发环境设置的cookie设置

if (process.env.NODE_ENV === 'development'``) {

document.cookie.split(``';'``).forEach(item => {

const cookie = item.split(``'='``)

if (cookie[0].includes(``'_DEV'``)) {

document.cookie = cookie[0].slice(0, cookie[0].length - 4) + '=' + cookie[1]

}})

}

},

3. 总结

目前这样处理是由于我们测试环境一级域名与正式环境一级域名相同,一种比较hack的处理。

如果之后测试环境可以申请单独的域名 如 .intra.xiaojukeji.biz 那我们只需要开发环境host 改为 local.intra.xiaojukeji.biz 就不需要这样处理了。