minio实现后端授权,前端直接上传
minio安装
安装方式(已安装可跳过此步骤)
https://min.io/download#/linux
后端授权
添加依赖
<dependency>
<groupId>io.minio</groupId>
<artifactId>minio</artifactId>
<version>8.3.7</version>
</dependency>
代码
package com.controller;
import io.minio.GetPresignedObjectUrlArgs;
import io.minio.MinioClient;
import io.minio.errors.*;
import io.minio.http.Method;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import java.io.IOException;
import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException;
import java.util.UUID;
/**
* @author qc
* @version 1.0
* @date 2022/4/10 16:53
*/
@RestController
@RequestMapping("/file")
public class FileController {
private static final String BUCKET_NAME = "test";
private static final String ENDPOINT = "http://localhost:9000";
private static final String ACCESSKEY = "minioadmin";
private static final String SECRETKEY = "minioadmin";
/**
* 获取minio上传路径
*
* @param name 文件名称
* @return java.lang.String 上传的url
* @author qc
* @date 2022/4/10 16:56
*/
@GetMapping("/upload/url")
public String getUploadUrl(String name) {
if (name == null || name.trim().length() == 0) {
name = UUID.randomUUID().toString();
}
String url = null;
MinioClient minioClient = MinioClient.builder()
.endpoint(ENDPOINT)
.credentials(ACCESSKEY, SECRETKEY)
.build();
try {
url = minioClient.getPresignedObjectUrl(GetPresignedObjectUrlArgs
.builder()
.bucket(BUCKET_NAME)
.object(name)
.method(Method.PUT)
.expiry(60 * 60 * 24)
.build());
} catch (ErrorResponseException | NoSuchAlgorithmException | InsufficientDataException | InternalException | InvalidKeyException | InvalidResponseException | IOException | XmlParserException | ServerException e) {
e.printStackTrace();
}
return url;
}
}
前端上传
<template>
<div>
<div style="width:30%;margin: auto">
<el-upload
v-loading="loading"
class="avatar-uploader"
multiple
:show-file-list="false"
:http-request="toUpload"
>
<img v-if="imgUrl" :src="imgUrl" class="avatar"/>
<el-icon v-else class="avatar-uploader-icon">
<Plus/>
</el-icon>
</el-upload>
<div style="margin-top: 10px">
<el-progress :text-inside="true" :stroke-width="20" v-if="progress>0&&progress<100" :percentage="progress" style="margin: auto;width:178px " />
</div>
</div>
</div>
</template>
<script>
import {
Plus
} from '@element-plus/icons-vue'
import axios from "axios";
export default {
name: "FileUpload",
components: {
Plus
},
data() {
return {
imgUrl: null,
loading:false,
progress:0,
}
},
methods: {
toUpload(file) {
//调用后端接口获取minio带签名的上传地址
axios.get("http://localhost:8080/file/upload/url").then(res => {
let url = res.data
this.loading=true
//将文件上传到后端返回的minio服务器
axios.put(url, file.file, {
headers: {"Content-Type": file.file.type}, onUploadProgress: this.onUploadProgress}).then(r => {
this.imgUrl = url.split("?")[0]
this.loading=false
console.log(r);
})
})
return true
},
onUploadProgress(progressEvent){
this.progress=((progressEvent.loaded * 100) / progressEvent.total).toFixed(2)
}
}
}
</script>
<style scoped>
.avatar-uploader .avatar {
width: 178px;
height: 178px;
display: block;
}
</style>
<style>
.avatar-uploader .el-upload {
border: 1px dashed var(--el-border-color);
border-radius: 6px;
cursor: pointer;
position: relative;
overflow: hidden;
transition: var(--el-transition-duration-fast);
}
.avatar-uploader .el-upload:hover {
border-color: var(--el-color-primary);
}
.el-icon.avatar-uploader-icon {
font-size: 28px;
color: #8c939d;
width: 178px;
height: 178px;
text-align: center;
}
</style>