前提:开发环境
在前端业务服务和鉴权服务分离的场景中,可以选择将登录操作托管给代理服务器,并将鉴权信息保存至代理服务器中。既可以将登录、鉴权信息过期处理等操作自动化,也可以减少反复登录的次数,从而提高开发效率。
流程:
1、前端请求发送至代理服务器
2、代理服务器转发请求至后端
3、后端响应为缺少鉴权信息或者鉴权信息过期,则进行以下步骤进行登录
一、NodeJs启动chrome浏览器
import { spawn } from 'child_process';
const chromePath = 'C:/Program Files/Google/Chrome/Application/chrome.exe';
async function startChromeWithRemoteDebugging() {
// 启动 Chrome 浏览器
const chrome = spawn(chromePath, [
'--remote-debugging-port=9222',
'--no-first-run',
'--user-data-dir=D:/cdp'
]);
return new Promise(resolve => {
// 监听Chrome的输出,启动成功后抛出结果
chrome.stdout.on('data', (data) => {
console.log(`stdout: ${data}`);
resolve(null);
});
})
}
二、打开登录界面,并获取cookie
监听打开窗口的接口
import CDP from 'chrome-remote-interface';
async function listenChrome() {
return new Promise(async resolve => {
let client;
try {
// 连接到端点
client = await CDP();
// 提取域
const {Network, Page} = client;
// 设置处理器,监听接口
// 监听接口
Network.requestWillBeSent((params) => {
// params.request.url 页面请求的url
// Network.getCookies() 获取页面cookie
if (params.request.url.includes('/rest/me')) {
Network.getCookies().then(cookies => resolve(cookies?.cookies || []));
}
});
// 启用事件然后开始!
await Network.enable();
await Page.enable();
await Page.navigate({url: authKeys.envHost});
await Page.loadEventFired();
} catch (err) {
console.error(err);
} finally {
if (client) {
await client.close();
}
}
})
}
三、保存cookies
export function login() {
startChromeWithRemoteDebugging()
.then(() => {
return listenChrome();
})
.then((cookies: any) => {
// todo: 保存cookie至本地,供代理服务器使用
});
}