当前位置: 首页 > news >正文

MinIO - 服务端签名直传(前端 + 后端 + 效果演示)

目录

开始

服务端签名直传概述

代码实现

后端实现

前端实现

效果演示


开始


服务端签名直传概述

传统的,我们有两种方式将图片上传到 OSS:

a)前端请求 -> 后端服务器 -> OSS 

好处:在服务端上传,更加安全.

坏处:给服务器带来压力.

b)直接写在前端 js 代码中

好处:效率高,不用给服务器带来额外压力.

坏处:危险,用户直接可以看得到 OSS账号密码 信息.

因此最好的方式就是 服务端签名直传:用户直接去服务器请求获取上传签名(账号密码加密生成的防伪签名,一般有过期时间),服务器就返回防伪签名,然后用户就可以拿着签名和要上传的文件,通过表单直接上传到 OSS 中.

此时既不需要服务端承担上传文件到 OSS 中的压力,也保证了 OSS账号密码 信息的安全性.

代码实现

后端实现

a)配置文件

minio:access-key: rootsecret-key: rootrootendpoint: http://100.105.180.32:9001bucket: dir1

b)Bean 配置 

import org.springframework.context.annotation.Configuration
import io.minio.MinioClient
import org.springframework.beans.factory.annotation.Value
import org.springframework.context.annotation.Bean@Configuration
class MinioConfig {@Value("\${minio.access-key}")private lateinit var accessKey: String@Value("\${minio.secret-key}")private lateinit var secretKey: String@Value("\${minio.endpoint}")private lateinit var endpoint: String@Beanfun minioClient(): MinioClient = MinioClient.builder().endpoint(endpoint) //格式必须是 http://ip:port  注意: 这里使用的 9001 端口,而不是 9000.credentials(accessKey, secretKey) //用户名 和 密码.build()}

c)核心代码

@RestController
@RequestMapping("/third/minio")
class MinioApi(private val minioClient: MinioClient
) {@Value("\${minio.endpoint}")private lateinit var endpoint: String@Value("\${minio.bucket}")private lateinit var bucket: String@GetMapping("/policy")fun policy(): Map<String, String> {val objectNamePrefix =  "uploads/"// 设置过期时间为当前时间加1小时val expiration = ZonedDateTime.now().plusHours(1)val postPolicy = PostPolicy(bucket, expiration)postPolicy.run {//添加条件,确保字段的值以指定前缀开头,前端指定 key 时,也需要加上该前缀,否则 403addStartsWithCondition("key", objectNamePrefix)//添加条件,将文件大小范围限制在 1 ~ 10485760 (1 到 10 MB)addContentLengthRangeCondition(1, 10485760)}val result = minioClient.getPresignedPostFormData(postPolicy).apply {//这里是给前端构造 Minio 请求的this["url"] = "$endpoint/$bucket"}return result}}

前端实现

<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><meta name="viewport" content="width=device-width, initial-scale=1.0"><title>Minio File Upload</title>
</head>
<body>
<h2>Minio 文件上传</h2>
<input type="file" id="fileInput" />
<button onclick="uploadFile()">上传</button><script>async function uploadFile() {const fileInput = document.getElementById('fileInput');if (!fileInput.files.length) {alert('请选择文件');return;}const file = fileInput.files[0];const response = await fetch('http://localhost:10010/third/minio/policy');const formData = await response.json();const data = new FormData();for (const [key, value] of Object.entries(formData)) {data.append(key, value);}// 构建对象键(这里一定要和 后端 那里的设定的前缀一致,否则 403)const objectName = 'uploads/' + file.name;data.append('key', objectName);data.append('file', file);// 上传 URLconst uploadUrl = formData['url'];const uploadResponse = await fetch(uploadUrl, {method: 'POST',body: data,});if (uploadResponse.ok) {alert('上传成功');} else {alert('上传失败');}}
</script>
</body>
</html>

效果演示

a)点击选择文件,选择 mongo.png

b)点击上传

c)返回 MinIO 控制台,就可以看到文件已经长传成功~

相关文章:

  • 北京网站建设多少钱?
  • 辽宁网页制作哪家好_网站建设
  • 高端品牌网站建设_汉中网站制作
  • git查看版本,查看安装路径、更新版本
  • 图解 RocketMQ 架构
  • 三星首款智能戒指 Galaxy Ring 将于7月24日上市,售价399美元
  • 深入理解 KVO
  • 【2024最新华为OD-C/D卷试题汇总】[支持在线评测] 找单词(200分) - 三语言AC题解(Python/Java/Cpp)
  • 真实测评网上较火的两款智能生成PPT产品:秒出PPTAI PPT
  • uni-app/vue项目如何封装全局消息提示组件
  • Java接口案例
  • HTML 标签简写和全称及其对应的中文说明和实例
  • SQL MySQL定时器/事件调度器(Event Scheduler)
  • Deepspeed : AttributeError: ‘DummyOptim‘ object has no attribute ‘step‘
  • (Windows环境)FFMPEG编译,包含编译x264以及x265
  • 7.深度学习概述
  • Java毕业设计 基于SSM vue图书管理系统小程序 微信小程序
  • Armbian 1panel面板工具箱中FTP服务无法正常启动的解决方法
  • Apache Zeppelin在Apache Trafodion上的可视化
  • classpath对获取配置文件的影响
  • download使用浅析
  • IDEA常用插件整理
  • Java的Interrupt与线程中断
  • mysql 数据库四种事务隔离级别
  • 闭包--闭包作用之保存(一)
  • 不发不行!Netty集成文字图片聊天室外加TCP/IP软硬件通信
  • 对话 CTO〡听神策数据 CTO 曹犟描绘数据分析行业的无限可能
  • 分布式熔断降级平台aegis
  • 力扣(LeetCode)965
  • 马上搞懂 GeoJSON
  • 用mpvue开发微信小程序
  • ionic异常记录
  • ​第20课 在Android Native开发中加入新的C++类
  • # 再次尝试 连接失败_无线WiFi无法连接到网络怎么办【解决方法】
  • (04)odoo视图操作
  • (2)Java 简介
  • (4)事件处理——(2)在页面加载的时候执行任务(Performing tasks on page load)...
  • (Java入门)抽象类,接口,内部类
  • (libusb) usb口自动刷新
  • (PADS学习)第二章:原理图绘制 第一部分
  • (PWM呼吸灯)合泰开发板HT66F2390-----点灯大师
  • (python)数据结构---字典
  • (附源码)springboot建达集团公司平台 毕业设计 141538
  • (附源码)springboot炼糖厂地磅全自动控制系统 毕业设计 341357
  • (含react-draggable库以及相关BUG如何解决)固定在左上方某盒子内(如按钮)添加可拖动功能,使用react hook语法实现
  • (求助)用傲游上csdn博客时标签栏和网址栏一直显示袁萌 的头像
  • (三)Kafka离线安装 - ZooKeeper开机自启
  • (杂交版)植物大战僵尸
  • .java 指数平滑_转载:二次指数平滑法求预测值的Java代码
  • .Net 6.0--通用帮助类--FileHelper
  • .NET 8.0 中有哪些新的变化?
  • .NET Standard、.NET Framework 、.NET Core三者的关系与区别?
  • .net web项目 调用webService
  • .net2005怎么读string形的xml,不是xml文件。
  • .Net程序猿乐Android发展---(10)框架布局FrameLayout
  • @ 代码随想录算法训练营第8周(C语言)|Day53(动态规划)
  • @Repository 注解
  • @select 怎么写存储过程_你知道select语句和update语句分别是怎么执行的吗?