简介
最近在用 FastAPI 和 Vue 开发项目时,发现 FastAPI 默认使用 http 协议。这导致在访问网站时会出现"不安全"警告,严重影响用户体验。因此,决定将项目升级到 https。
为什么需要 https?
主要是从安全性以及用户体验考虑,
安全性上:
http 通过 SSL/TLS 协议对数据进行加密,防止数据在传输过程中被窃听或篡改;
可以保护用户敏感信息(如密码、个人信息等)的安全;
确保网站内容的完整性,防止中间人攻击。
用户体验上:
浏览器对 http 网站会显示"不安全"警告;
部分浏览器功能(如地理位置、摄像头等)要求必须使用 https;
有利于搜索引擎优化(SEO),Google 会优先考虑 https 网站。
接下来是我记录的这次替换过程。
1 前端
首先是 web 和前端部分,之前在部署过程中用的是 nginx ,主要是可以通过宝塔面板进行可视化操作;但是在替换 https 的过程中换成了更加轻量,简单的 caddy。
1.1 为什么选择 Caddy?
相比传统的 Nginx,Caddy 有以下优势:
自动 https:
自动申请和续期 Let's Encrypt 证书
零配置 https 支持,大大简化了配置过程
简单易用:
配置文件语法简洁明了
默认配置已经很安全,无需额外的安全配置
内置了现代 Web 特性支持
轻量:
资源占用少
启动快速
依赖少,易于部署
1.2 安装 caddy
caddy官方文档:Welcome — Caddy Documentation
ubuntu:
sudo apt install -y debian-keyring debian-archive-keyring apt-transport-https curl
curl -1sLf 'https://dl.cloudsmith.io/public/caddy/stable/gpg.key' | sudo gpg --dearmor -o /usr/share/keyrings/caddy-stable-archive-keyring.gpg
curl -1sLf 'https://dl.cloudsmith.io/public/caddy/stable/debian.deb.txt' | sudo tee /etc/apt/sources.list.d/caddy-stable.list
sudo apt update
sudo apt install caddy
其他操作系统参考官方文档。
安装完成后要修改 caddy 的配置文件,/etc/caddy/Caddyfile
。
以下是一个简单的配置文件:
example.com {
# 根目录设置
root * /var/www/example.com
# 启用文件服务器
file_server
# 启用单页应用支持
try_files {path} /index.html
# 启用压缩
encode gzip
# 基本安全头
header {
X-Frame-Options "SAMEORIGIN"
X-Content-Type-Options "nosniff"
}
}
重新启动
sudo systemctl restart caddy
前端部分只需要将原本发送 http 请求部分改为 https 即可,然后将 build 后的文件放在对应目录下即可。
1.3 证书
由于 caddy 会自动部署证书,所以这一步可以忽略。
2 后端
2.1 获取证书
FastAPI 要支持 https,需要配置 SSL 证书。我们可以通过 Python 生成一个自签名证书用于开发和测试。
注意:自签名证书仅建议用于开发环境。在生产环境中,应使用受信任的证书颁发机构(CA)签发的证书。比如可以使用 cloudflare 的证书。
首先安装依赖:
pip install pyOpenSSL
然后创建并执行以下文件:
from OpenSSL import crypto, SSL
def generate_certificate(
organization="PrivacyFilter",
common_name="<你的ipv4地址>:8000",
country="NL",
duration=(365 * 24 * 60 * 60),
keyfilename="key.pem",
certfilename="cert.pem"):
k = crypto.PKey()
k.generate_key(crypto.TYPE_RSA, 4096)
cert = crypto.X509()
cert.get_subject().C = country
cert.get_subject().O = organization
cert.get_subject().CN = common_name
cert.gmtime_adj_notBefore(0)
cert.gmtime_adj_notAfter(duration)
cert.set_issuer(cert.get_subject())
cert.set_pubkey(k)
cert.sign(k, 'sha512')
with open(keyfilename, "wt") as keyfile:
keyfile.write(crypto.dump_privatekey(crypto.FILETYPE_PEM, k).decode("utf-8"))
with open(certfilename, "wt") as certfile:
certfile.write(crypto.dump_certificate(crypto.FILETYPE_PEM, cert).decode("utf-8"))
if __name__ == '__main__':
generate_certificate()
成功执行后会生成
cert.pem (证书文件)
key.pem (私钥文件)
2.2 FastAPI 配置
在 FastAPI 应用中启用 https ,只需在启动时配置 SSL 证书:
import uvicorn
from fastapi import FastAPI
app = FastAPI()
if __name__ == "__main__":
uvicorn.run(
"main:app",
host="0.0.0.0",
port=8000,
ssl_keyfile="./key.pem",
ssl_certfile="./cert.pem"
)
2.3 方法二
上面这种方式还是向 ipv4 地址发送请求,所以只能使用自签证书。
我们也可以选择添加一个子域名解析到后端服务器,如果前后端是同一台服务器可以用 caddy 设置一个反向代理。
前面说到 caddy 可以自动部署证书,这样前端就可以向子域名发送 https 请求,同样实现了后端的升级。
3 其他
略微补充下 cloudflare 的证书获取以及如何使用宝塔面板中的 nginx 简单部署。
3.1 cloudfare 证书获取
3.1.1 cloudflare 简介
简单点说,Cloudflare 是一家提供 CDN、安全防护、DNS 解析等服务的全球性云服务提供商,通过其全球网络帮助网站提升访问速度、增强安全性和改善可靠性。
https://www.cloudflare.com/zh-cn/learning/what-is-cloudflare/
3.1.2 获取
找到管理的域名中的 SSL/TLS ,点击 Origin Server,右侧有一个Create Certificate
。
点击后填写你想获取证书的域名。
注意:例如你的域名是
example.com
那么你只需要填写example.com
即可,一定不要添加*.example.com
,否则会让所有子域名都重定向到主域名。
点击Create
后保存即可。
3.2 宝塔面板部署 SSL 证书
部署好站点之后找到 SSL ,分别将证书和私钥复制过来,点击启用并且强制 https 就好了。
评论区