前端安全直传MinIO方案
目的:前端直接上传文件到Minio,不通过服务器中转文件。密钥不能在前端明文传输。
## 一、架构设计
```mermaid
sequenceDiagram
前端->>后端: 1.请求上传凭证
后端->>MinIO: 2.生成预签名URL
后端-->>前端: 3.返回预签名URL
前端->>MinIO: 4.使用URL直传文件
MinIO-->>前端: 5.返回上传结果
```
---
## 二、服务端实现
### 1. 环境配置
```bash
# 安装依赖
npm install minio express dotenv cors
```
### 2. 安全凭证管理
```javascript
// .env文件
MINIO_ENDPOINT=your-minio.example.com
MINIO_PORT=9000
MINIO_USE_SSL=true
MINIO_ACCESS_KEY=your_access_key
MINIO_SECRET_KEY=your_secret_key
```
### 3. 预签名URL生成接口
```javascript
const Minio = require('minio')
const express = require('express')
const app = express()
require('dotenv').config()
const minioClient = new Minio.Client({
endPoint: process.env.MINIO_ENDPOINT,
port: parseInt(process.env.MINIO_PORT),
useSSL: process.env.MINIO_USE_SSL === 'true',
accessKey: process.env.MINIO_ACCESS_KEY,
secretKey: process.env.MINIO_SECRET_KEY
})
// 生成预签名上传URL
app.get('/api/upload-token', (req, res) => {
const fileId = `${Date.now()}-${Math.random().toString(36).substr(2, 9)}`
const objectName = `uploads/${fileId}/${req.query.fileName}`
const expiry = 15 * 60 // 15分钟有效期
minioClient.presignedPutObject(
process.env.MINIO_BUCKET,
objectName,
expiry,
(err, presignedUrl) => {
if (err) return res.status(500).json({ error: err.message })
res.json({
presignedUrl,
objectUrl: `https://${process.env.MINIO_ENDPOINT}/${process.env.MINIO_BUCKET}/${objectName}`
})
}
)
})
app.listen(3000, () => console.log('Server running on port 3000'))
```
---
## 三、前端实现
### 1. 获取上传凭证
```javascript
async function getUploadToken(fileName) {
const response = await fetch(`/api/upload-token?fileName=${encodeURIComponent(fileName)}`)
return response.json()
}
```
### 2. 文件上传组件
```html
<input type="file" id="fileInput" />
<button οnclick="uploadFile()">上传</button>
<script>
async function uploadFile() {
const fileInput = document.getElementById('fileInput')
const file = fileInput.files[0]
// 获取上传凭证
const { presignedUrl, objectUrl } = await getUploadToken(file.name)
// 直传MinIO
const result = await fetch(presignedUrl, {
method: 'PUT',
body: file,
headers: {
'Content-Type': file.type
}
})
if (result.ok) {
console.log('文件地址:', objectUrl)
} else {
console.error('上传失败')
}
}
</script>
```
---
## 四、安全增强措施
### 1. MinIO存储桶策略
```json
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Deny",
"Principal": "*",
"Action": "s3:*",
"Resource": "arn:aws:s3:::your-bucket/*",
"Condition": {
"NumericGreaterThan": {"s3:signatureAge": "900"}
}
},
{
"Effect": "Allow",
"Principal": "*",
"Action": "s3:PutObject",
"Resource": "arn:aws:s3:::your-bucket/uploads/*"
}
]
}
```
### 2. 服务端安全中间件
```javascript
// 添加CORS限制
const cors = require('cors')
app.use(cors({
origin: ['https://your-domain.com'],
methods: ['GET', 'POST'],
maxAge: 300
}))
// 请求频率限制
const rateLimit = require('express-rate-limit')
const limiter = rateLimit({
windowMs: 15 * 60 * 1000,
max: 100
})
app.use('/api/upload-token', limiter)
```
---
## 五、大文件分片上传
### 1. 前端分片处理
```javascript
async function uploadLargeFile(file) {
const CHUNK_SIZE = 5 * 1024 * 1024 // 5MB
const chunks = Math.ceil(file.size / CHUNK_SIZE)
// 初始化分片上传
const { uploadId } = await initMultipartUpload(file.name)
// 并发上传分片
const uploadPromises = []
for (let i = 0; i < chunks; i++) {
const chunk = file.slice(i * CHUNK_SIZE, (i + 1) * CHUNK_SIZE)
uploadPromises.push(uploadChunk(uploadId, i + 1, chunk))
}
await Promise.all(uploadPromises)
// 完成上传
return completeUpload(uploadId)
}
```
### 2. 分片上传服务端支持
```javascript
// 初始化分片上传
app.post('/api/multipart-init', (req, res) => {
const objectName = `uploads/${uuidv4()}/${req.query.fileName}`
minioClient.initiateNewMultipartUpload(
process.env.MINIO_BUCKET,
objectName,
(err, uploadId) => {
if (err) return res.status(500).send(err)
res.json({ uploadId, objectName })
}
)
})
// 获取分片上传URL
app.get('/api/multipart-url', (req, res) => {
const presignedUrl = minioClient.presignedPutObject(
process.env.MINIO_BUCKET,
req.query.objectName,
15 * 60,
{ partNumber: req.query.partNumber, uploadId: req.query.uploadId }
)
res.json({ presignedUrl })
})
```
---
## 六、监控与日志
### 1. MinIO操作日志
```bash
# 启用访问日志
mc admin config set myminio audit_webhook endpoint=http://log-server:3000/logs
```
### 2. 服务端监控指标
```javascript
const prometheus = require('prom-client')
const uploadCounter = new prometheus.Counter({
name: 'file_uploads_total',
help: 'Total number of file uploads',
labelNames: ['status']
})
app.post('/api/upload', (req, res) => {
uploadCounter.inc({ status: 'started' })
// ...上传逻辑
})
```
---
## 七、方案优势
1. **零密钥暴露**:前端仅使用临时预签名URL
2. **高安全性**:15分钟有效期+IP限制+HTTPS
3. **高性能**:支持5GB+大文件分片上传
4. **可扩展**:轻松集成CDN和自动转码
5. **合规性**:满足GDPR和等保要求
---
## 八、部署注意事项
1. 启用MinIO的HTTPS访问
2. 定期轮换MinIO根密钥
3. 设置存储桶生命周期策略
4. 监控存储桶使用情况
5. 启用防病毒扫描
6. 配置自动告警规则
```bash
# MinIO客户端配置示例
mc alias set myminio https://minio.example.com your_access_key your_secret_key
mc mb myminio/secure-uploads
mc lifecycle set myminio/secure-uploads lifecycle.json
```
---
通过该方案,前端可直接安全上传文件到MinIO,无需在后端保存中转文件,同时确保敏感凭证不会暴露在前端代码中。实际部署时建议结合具体业务需求调整安全策略和性能参数。
相关文章:
前端安全直传MinIO方案
目的:前端直接上传文件到Minio,不通过服务器中转文件。密钥不能在前端明文传输。 ## 一、架构设计 mermaid sequenceDiagram 前端->>后端: 1.请求上传凭证 后端->>MinIO: 2.生成预签名URL 后端-->>前端: 3.返回预签名URL 前端->…...

HackMyVM-Dejavu
信息搜集 主机发现 ┌──(root㉿kali)-[~] └─# arp-scan -l Interface: eth0, type: EN10MB, MAC: 00:0c:29:39:60:4c, IPv4: 192.168.43.126 Starting arp-scan 1.10.0 with 256 hosts (https://github.com/royhills/arp-scan) 192.168.43.1 c6:45:66:05:91:88 …...
LeetCode Hot100(动态规划)
70. 爬楼梯 题目: 假设你正在爬楼梯。需要 n 阶你才能到达楼顶。每次你可以爬 1 或 2 个台阶。你有多少种不同的方法可以爬到楼顶呢? 题解: 不难发现,每一次都是从i-1或者i-2爬上来的,我们加起来求和即可 class So…...

Opencv实用操作5 图像腐蚀膨胀
相关函数 腐蚀函数 img1_erosion cv2.erode(img1,kernel,iterations1) (图片,卷积核,次数) 膨胀函数 img_dilate cv2.dilate(img2,kernel1,iterations1) (图片,卷积核,次数)…...

【赵渝强老师】OceanBase的部署架构
OceanBase数据库支持无共享(Shared-Nothing,SN)模式和共享存储(Shared-Storage,SS)模式两种部署架构。 一、 无共享(Shared-Nothing,SN)模式 在SN模式下,各…...
(18)混合云架构部署
文章目录 🚀 混合云架构部署:Java应用的云原生之旅🌩️ 混合云架构简介⚡ Java应用云原生部署五大核心技术1️⃣ 容器化与编排技术2️⃣ 服务网格与API网关3️⃣ CI/CD自动化流水线4️⃣ 多云管理平台5️⃣ 云原生Java框架与运行时 …...
c/c++的opencv霍夫变换
OpenCV中的霍夫变换 (C/C) Hough Transform 霍夫变换 (Hough Transform) 是一种在图像分析中用于检测几何形状(如直线、圆形等)的特征提取技术。它通过一种投票机制在参数空间中寻找特定形状的实例。OpenCV 库为 C 开发者提供了强大且易用的霍夫变换函数…...
AAOS系列之(七) --- AudioRecord录音逻辑分析(一)
一文讲透AAOS架构,点到为止不藏私 📌 这篇帖子给大家分析下 AudioRecord的初始化 1. 场景介绍: 在 AAOS 的 Framework 开发中,录音模块几乎是每个项目都会涉及的重要组成部分。无论是语音控制、车内对讲(同行者模式)…...
MySQL大表结构变更利器:pt-online-schema-change原理与实战指南
MySQL大表结构变更利器:pt-online-schema-change原理与实战指南 MySQL数据库运维中,最令人头疼的问题之一莫过于对大表进行结构变更(DDL操作)。传统的ALTER TABLE操作会锁表,导致业务长时间不可用,这在724小时运行的互联网业务中是不可接受的。本文将深入剖析Percona To…...

LangChain【3】之进阶内容
文章目录 说明一 LangChain Chat Model1.1 少量示例提示(Few-Shot Prompting)1.2 Few-Shot示例代码1.3 示例选择器(Eample selectors)1.4 ExampleSelector 类型1.5 ExampleSelector案例代码1.6 LangServe工具1.7 LangServe安装1.8 langchain项目结构1.9 …...

大规模JSON反序列化性能优化实战:Jackson vs FastJSON深度对比与定制化改造
背景:500KB JSON处理的性能挑战 在当今互联网复杂业务场景中,处理500KB以上的JSON数据已成为常态。 常规反序列化方案在CPU占用(超30%)和内存峰值(超原始数据3-5倍)方面表现堪忧。 本文通过Jackson与Fas…...
【OpenSearch】高性能 OpenSearch 数据导入
高性能 OpenSearch 数据导入 1.导入依赖库2.配置参数3.OpenSearch 客户端初始化4.创建索引函数5.数据生成器6.批量处理函数7.主导入函数7.1 函数定义和索引创建7.2 优化索引设置(导入前)7.3 初始化变量和打印开始信息7.4 线程池设置7.5 主数据生成和导入…...
HTML5有那些更新
语义化标签 header 头部nav 导航栏footer 底部aside 内容的侧边栏 媒体标签 audio 音频播放video 视频播放 dom查询 document.querySelector,document.querySelectorAll他们选择的对象可以是标签,也可以是类(需要加点),也可以是ID(需要加#) web存储 localStorage和sessi…...

AWS EC2 实例告警的创建与删除
在AWS云环境中,监控EC2实例的运行状态至关重要。通过CloudWatch告警,用户可以实时感知实例的CPU、网络、磁盘等关键指标异常。本文将详细介绍如何通过AWS控制台创建EC2实例告警,以及如何安全删除不再需要的告警规则,并附操作截图与…...

STM32 搭配 嵌入式SD卡在智能皮电手环中的应用全景评测
在智能皮电手环及数据存储技术不断迭代的当下,主控 MCU STM32H750 与存储 SD NAND MKDV4GIL-AST 的强强联合,正引领行业进入全新发展阶段。二者凭借低功耗、高速读写与卓越稳定性的深度融合,以及高容量低成本的突出优势,成为大规模…...

黑马点评项目01——短信登录以及登录校验的细节
1.短信登录 1.1 Session方式实现 前端点击发送验证码,后端生成验证码后,向session中存放键值对,键是"code",值是验证码;然后,后端生成sessionID以Cookie的方式发给前端,前端拿到后&a…...

【笔记】Windows 系统安装 Scoop 包管理工具
#工作记录 一、问题背景 在进行开源项目 Suna 部署过程中,执行设置向导时遭遇报错:❌ Supabase CLI is not installed. 根据资料检索,需通过 Windows 包管理工具Scoop安装 Supabase CLI。 初始尝试以管理员身份运行 PowerShell 安装 Scoop…...
LVS + Keepalived高可用群集
目录 一:keepalived双击热备基础知识 1.keepalived概述及安装 1.1keepalived的热备方式 1.2keepalived的安装与服务控制 (1)安装keepalived (2)控制keepalived服务 2.使用keepalived实现双击热备. 2.1主服务器的…...

MySQL之约束和表的增删查改
MySQL之约束和表的增删查改 一.数据库约束1.1数据库约束的概念1.2NOT NULL 非空约束1.3DEFAULT 默认约束1.4唯一约束1.5主键约束和自增约束1.6自增约束1.7外键约束1.8CHECK约束 二.表的增删查改2.1Create创建2.2Retrieve读取2.3Update更新2.4Delete删除和Truncate截断 一.数据库…...
Greenplum:PB级数据分析的分布式引擎,揭开MPP架构的终极武器
一、Greenplum是谁?—— 定位与诞生背景 核心定位:基于PostgreSQL的开源分布式分析型数据库(OLAP),专为海量数据分析设计,支撑PB级数据仓库、商业智能(BI)和实时决策系统。 诞生背…...

Oracle数据库性能优化的最佳实践
原创:厦门微思网络 以下是 Oracle 数据库性能优化的最佳实践,涵盖设计、SQL 优化、索引管理、系统配置等关键维度,帮助提升数据库响应速度和稳定性: 一、SQL 语句优化 1. 避免全表扫描(Full Table Scan)…...
云原生时代 Kafka 深度实践:02快速上手与环境搭建
2.1 本地开发环境搭建 单机模式安装 下载与解压:前往Apache Kafka 官网,下载最新稳定版本的 Kafka 二进制包(如kafka_2.13-3.6.0.tgz,其中2.13为 Scala 版本)。解压到本地目录,例如/opt/kafka:…...
Redis7 新增数据结构深度解析:ListPack 的革新与优化
Redis 作为高性能的键值存储系统,其核心优势之一在于丰富的数据结构。随着版本迭代,Redis 不断优化现有结构并引入新特性。在 Redis 7.0 中,ListPack 作为新一代序列化格式正式登场,替代了传统的 ZipList(压缩列表&…...
分布式爬虫架构设计
随着互联网数据的爆炸式增长,单机爬虫已经难以满足大规模数据采集的需求。分布式爬虫应运而生,它通过多节点协作,实现了数据采集的高效性和容错性。本文将深入探讨分布式爬虫的架构设计,包括常见的架构模式、关键技术组件、完整项…...

汽配快车道:助力汽车零部件行业的产业重构与数字化出海
汽配快车道:助力汽车零部件行业的数字化升级与出海解决方案。 在当今快速发展的汽车零部件市场中,随着消费者对汽车性能、安全和舒适性的要求不断提高,汽车刹车助力系统作为汽车安全的关键部件之一,其市场需求也在持续增长。汽车…...

Windows 11 家庭版 安装Docker教程
Windows 家庭版需要通过脚本手动安装 Hyper-V 一、前置检查 1、查看系统 快捷键【winR】,输入“control” 【控制面板】—>【系统和安全】—>【系统】 2、确认虚拟化 【任务管理器】—【性能】 二、安装Hyper-V 1、创建并运行安装脚本 在桌面新建一个 .…...

PyQt6基础_QtCharts绘制横向柱状图
前置: pip install PyQt6-Charts 结果: 代码: import sysfrom PyQt6.QtCharts import (QBarCategoryAxis, QBarSet, QChart,QChartView, QValueAxis,QHorizontalBarSeries) from PyQt6.QtCore import Qt,QSize from PyQt6.QtGui import QP…...

《TCP/IP 详解 卷1:协议》第2章:Internet 地址结构
基本的IP地址结构 分类寻址 早期Internet采用分类地址(Classful Addressing),将IPv4地址划分为五类: A类和B类网络号通常浪费太多主机号,而C类网络号不能为很多站点提供足够的主机号。 子网寻址 子网(Su…...
Python学习(5) ----- Python的JSON处理
下面是关于 Python 中如何全面处理 JSON 的详细说明,包括模块介绍、数据类型映射、常用函数、文件操作、异常处理、进阶技巧等。 🧩 一、什么是 JSON? JSON(JavaScript Object Notation)是一种轻量级的数据交换格式&a…...

如何通过一次需求评审,让项目效率提升50%?
想象一下,你的团队启动了一个新项目,但需求模糊不清,开发到一半才发现方向错了,返工、加班、客户投诉接踵而至……听起来像噩梦?一次完美的需求评审就能避免这一切!它就像项目的“导航仪”,确保…...