前端项目本地环境配置 HTTPS 以及在移动端使用的设置

1,274 阅读5分钟

背景

iOS WebView 中打开本地页面竟然白屏,最后发现是只支持 HTTPS。于是研究了一下前端本地环境怎么配置 HTTPS。

技术:Vite + Vue

mkcert

要想是完成 HTTPS 的配置,就要在本地开发服务器上设置 SSL 证书。

提到安装证书必然就是 mkcertmkcert 是一个用 GO 写的零配置专门用来本地环境 https 证书生成的工具。

安装 mkcert 工具

但是 Windows 下安装似乎有点麻烦,官网下载:github.com/FiloSottile…mkcert-v1.4.4-windows-amd64.exe,不需要运行。

创建本地 CA

将 exe 文件拖入在命令行中,加上 -install 回车安装。

也就是相当于执行:mkcert -install

mkcert 会自动将其安装到系统信任存储中,这样由它签发的证书就会被系统信任。

生成 SSL 证书

mkcert 127.0.0.1 #创建IP证书
mkcert xxx.com #或创建域名证书

需要指定想要证书支持的域名,对于本地开发,通常是 localhost 或者本地 IP。执行完成后会在在当前目录生成 {ip或域名}-key.pem{ip或域名}.pem 文件。一个是证书文件,一个是私钥文件。

前端项目中使用

以上 mkcert 部分介绍了一般使用 mkcert 生成证书的方法。对于前端项目还需要配置开发服务器使用 SSL 证书。

在 Webpack 中使用

module.exports = {
  devServer: {
    https: true,
    key: fs.readFileSync('path/127.0.0.1-key.pem'),
    cert: fs.readFileSync('path/127.0.0.1.pem')
  }
};

在 Node.js 中使用

const https = require('node:https');
const fs = require('node:fs');

const options = {
  key: fs.readFileSync('path/127.0.0.1-key.pem'),
  cert: fs.readFileSync('path/127.0.0.1.pem')
};

https.createServer(options, (req, res) => {
  res.writeHead(200);
  res.end('hello world\n');
}).listen(8000);

在 Vite 中使用

image.png

直接使用

server: {
    https: {
      key: fs.readFileSync('C:/Users/choreau/127.0.0.1-key.pem'),
      cert: fs.readFileSync('C:/Users/choreau/127.0.0.1.pem'),
    },
    host: '0.0.0.0',
    port: 5173,
  },

使用插件 @vitejs/plugin-basic-ssl

Vite 官网推荐使用 @vitejs/plugin-basic-ssl

Vite 配置:

// vite.config.ts
import basicSsl from '@vitejs/plugin-basic-ssl'

export default defineConfig({
  plugins: [
    basicSsl()
  ]
})

使用这个插件,会自动创建签名证书,但是浏览器报错:您的连接不是私密连接。需要手动信任。

不推荐使用。

使用插件 vite-plugin-mkcert

使用这个插件,浏览器不会报错。

// vite.config.ts
import mkcert from 'vite-plugin-mkcert'

export default defineConfig({
  server: {
    https: true
  },
  plugins: [mkcert()]
})

这个插件的原理是使用 mkcert 安装本地 CA 证书,并为 server.https 生成服务端证书。

所以使用这个插件也不需要单独使用 mkcert 安装根证书和 SSL 证书。

使用 http-server 启动

关于任意的静态文件,可以使用 http-server 启动服务。也支持自定义证书,启动命令也只需要一行命令。

# 可以全局安装
npm i -g http-server

# 启动服务
http-server

# 启动服务并使用自定义证书
http-server -c-1 --ssl --cert {ssl cert文件} --key {ssl key文件}

关于根证书的位置

关于根证书的位置,我在命令行中 -install 的时候,并没有显示安装的位置:

image.png

有的文章中安装截图有显示安装位置。

有的文章提到可以使用 mkcert -CAROOT 命令打印它所在的文件夹。但是因为我这里没有正常安装,mkcert 无法使用,就通过文件搜索的方式找到。

其中,后面使用 Vite 插件的方式,根证书在 /当前用户名/.vite-plugin-mkcert 文件夹下。

这个根证书 rootCA.pem 后面移动端会用到。

移动端使用

最终,Vite 项目使用的是插件 vite-plugin-mkcert,这种方式,PC 上可以直接访问 HTTPS。因为本质上 mkcert -install 完成时会将根证书安装在 PC 上,PC 浏览器可以直接通过 HTTPS 协议访问本地 Web。但是对于移动设备需要安装根证书才能正常访问。

未信任本地证书

如果未安装根证书:

微信扫码,打开页面空白,应该是 WebView 阻止了。

浏览器中打开,会出现(以下是 Chrome):

0cf7d2bc6bd47f31fa41cbdf557777e.jpg

点击高级,可以继续前往页面地址,仍然可以打开页面。

以上的表现,也跟在 PC 上使用 Vite 插件 @vitejs/plugin-basic-ssl,浏览器或者系统未信任本地证书表现一样。

但是对于 APP WebView,页面会被阻止,所以我们需要在手机上安装根证书,使得由其签发的证书会被系统信任。

手机上安装根证书的问题

安卓,我这里暂时略过,说 iOS。

下载根证书,保存到档案中,然后“设置”中会多一个已下载文件,安装。

在给测试的手机上安装了根证书之后,iOS APP WebView 仍然打不开页面,页面空白。此时有点陷入困境,于是和各方沟通,怀疑证书问题或者 WebView 不支持 IP 的方式。(后来发现,不必要在 iOS APP 里测试呀,首先至少要在手机浏览器上能正常打开,而且也没必要用装有 APP 的测试机。)

于是先自己测试,给一台 iOS 设备发送了根域名,安装,测试。根据 www.npmjs.com/package/vit… ,也是来自 mkcert 的 README,上面说可以通过 AirDrop email http 等方式发送,我一度怀疑是通过聊天软件发送文件不行吗?

image.png

后来再反复阅读文档,github.com/FiloSottile…, 发现自己安装的过程和它好像不一样,好像并没有看到过 Certificate Trust Settings,之前想着既然安装成功就没影响吧。

image.png

然后通读了完整的 issue,以及它相关的 github.com/FiloSottile… ,最后才明白这个 issue 是在说,正常安装了证书,为什么没有出现在 Certificate Trust Settings。于是才发现还有个 证书信任设置 的设置。(顺便说下,issue 的问题是为什么安装了证书没有出现在证书信任设置中,针对 github.com/FiloSottile… 的回答,可能是由于 iOS 更新,作者并没有正确安装证书,正确的如回答中的截图)

于是解决就是去证书信任设置开启根证书信任,前往“设置”>“通用”>“关于本机”>“证书信任设置”。在“针对根证书启用完全信任”下,开启对这个证书的信任。

image.png

后来也发现其实它的 enable full trust in it 也说明了这一点,我没点进去看。

参考