Electron 跨域
因为Chrome 内核的限制,Electron 不能获取第三方站点的set-cookie
信息,从而无法保存用户登登录状态。
自定义消息
本来以为自定义消息可以解决跨域不能设置cookie
的问题,但是后来发现并不能。
const { protocol } = require('electron');
const path = require('path');
// fix cros issue: https://stackoverflow.com/a/57216953/14791867
protocol.registerSchemesAsPrivileged([{
scheme: 'app',
privileges: {
standard: true,
secure: true
}
}]);
app.whenReady().then(() => {
// fix cros issue: https://stackoverflow.com/a/57216953/14791867
// and: https://www.electronjs.org/zh/docs/latest/api/protocol
protocol.registerFileProtocol('app', (request, callback) => {
const filePath = path.normalize(`${__dirname}/${request.url.slice('app://'.length)}`)
console.log(filePath);
callback(filePath)
})
}
拦截HTTP 消息
通过修改消息头,可以让Electron 误认为SameSite=None; Secure
,但是要求链接必须是https
的。没办法,只能设置自签名证书了。
app.whenReady().then(() => {
// fixed electron CROS issue: https://cloud.tencent.com/developer/article/2137540
session.defaultSession.webRequest.onHeadersReceived(
{ urls: ['*://*/*'] },
(details, callback) => {
if (
details.responseHeaders &&
details.responseHeaders['Set-Cookie'] &&
details.responseHeaders['Set-Cookie'].length &&
!details.responseHeaders['Set-Cookie'][0].includes('SameSite=none')
) {
for (var i = 0; i < details.responseHeaders['Set-Cookie'].length; i++) {
details.responseHeaders['Set-Cookie'][i] += '; SameSite=None; Secure';
}
details.responseHeaders['Access-Control-Allow-Origin'] = ['*']
}
callback({ cancel: false, responseHeaders: details.responseHeaders });
},
);
}
生成自签名证书
在Ubuntu 下生成自签名证书的过程,可以参考SSL 自签证书和创建自用CA根证书并颁发自签名的泛域名证书
# 1. 创建CA 私钥
openssl genrsa -des3 -out ca.key 4096
# 2. 创建CA 公钥
openssl req -x509 -new -key ca.key -out ca.pem -days 3650 # 10 年
# 需要填写国家地区等信息
# 3. 创建自签名服务私钥(可用于Nginx等程序)
openssl genrsa -out server.key 2048 # 即Nginx中的ssl_certificate_key参数
# 4. 创建自签名请求
openssl req -new -key server.key -out server.csr # Common Name: *.12tall.cn
# 5. 生成签名证书
openssl x509 -req -CAkey ca.key -CA ca.pem -in server.csr -out server.pem -CAcreateserial -days 3650
# 6. 创建Server证书之后,与Ca证书合成完整的证书链
cat ca.pem server.pem > full-cert.pem
Nginx 配置
server {
# ...
ssl_certificate server/full.pem;
ssl_certificate_key server/server-key.pem;
# ...
}
Electron 忽略证书错误
app.commandLine.appendSwitch('--ignore-certificate-errors', 'true')
app.on('certificate-error', (event, webContents, url, error, certificate, callback) => {
event.preventDefault()
callback(true)
});
因为个人比较懒,生成了一个100
年的证书,再配合上面的各种办法,一劳永逸了。