前台使用vue+axios
后台springboot
现在这里有一个需求,是用户直接网页上传头像到cos,同时删除原来的头像,上传这部分操作是在浏览器完成,然后为了安全,删除的操作在服务器完成,关键代码如下:
前台
uploadAvatar方法(由input[type=file] onchange触发)
uploadAvatar(e) {
if (!e.target.files[0]) return;
let fileObj = e.target.files[0]; // js 获取文件对象
console.log(fileObj);
// 扩展名
let extName = fileObj.name.split('.').pop().toLowerCase();
// 图片名称
let random = Math.random().toString(36).slice(-8);
let avatarName = _self.$store.getters.user.userId + random + '.' + extName;
// 对象存储的key值
let key = '/user/avatar/' + avatarName;
TencentCos.putObject(fileObj, key, (url) => {
console.log(url);
_self.$axios.post('/userInfo/updateUserAvatarByUserId', {
userId: _self.$store.getters.user.userId,
userAvatar: url
}).then(res => {
if (res.data.code == 200) {
_self.userInfo.userAvatar = url;
_self.$store.dispatch({
type: 'login',
userInfo: res.data.data
})
_self.$message({
message: '更新头像成功',
type: 'success'
})
}
})
});
},
获取临时密钥的controller,FunctionController.java
@RequestMapping("getTencentCosTempKey")
public ResponseData getTencentCosTempKey() {
TreeMap<String, Object> config = new TreeMap<String, Object>();
try {
// 替换为您的 SecretId
config.put("SecretId", SECRET_ID);
// 替换为您的 SecretKey
config.put("SecretKey", SECRET_KEY);
// 临时密钥有效时长,单位是秒
config.put("durationSeconds", 1800);
// 换成您的 bucket
config.put("bucket", BUCKET);
// 换成 bucket 所在地区
config.put("region", REGION);
// 这里改成允许的路径前缀,可以根据自己网站的用户登录态判断允许上传的目录
config.put("allowPrefix", "*");
// 密钥的权限列表。简单上传、表单上传和分片上传需要以下的权限,其他权限列表请看
// https://cloud.tencent.com/document/product/436/31923
String[] allowActions = new String[] {
// 简单上传
"name/cos:PutObject",
// 表单上传、小程序上传
"name/cos:PostObject",
// 下载对象
"name/cos:GetObject",
// 分片上传
"name/cos:InitiateMultipartUpload", "name/cos:ListMultipartUploads", "name/cos:ListParts",
"name/cos:UploadPart", "name/cos:CompleteMultipartUpload" };
config.put("allowActions", allowActions);
JSONObject credential = CosStsClient.getCredential(config);
String jsonString = credential.get("credentials").toString();
CosCredential cosCredential = MAPPER.readValue(jsonString, CosCredential.class);
cosCredential.setExpiredTime((Integer) credential.get("expiredTime")).setBucket(BUCKET).setRegion(REGION);
// 成功返回临时密钥信息,如下打印密钥信息
return new ResponseData(200, "获取临时密钥成功", cosCredential);
} catch (Exception e) {
// 失败抛出异常
// throw new IllegalArgumentException("no valid secret !");
e.printStackTrace();
return new ResponseData(500, "获取临时密钥失败", null);
}
}
用户信息controller
UserInfoController.java
@RequestMapping("updateUserAvatarByUserId")
public ResponseData updateUserAvatarByUserId(UserInfo userInfo) {
System.out.println(userInfo);
userInfo.setUserTime(null);
UserInfo userInfoQuery = userInfoService.query().eq("user_id", userInfo.getUserId()).one();
if (userInfoQuery == null) {
return new ResponseData(500, "更新失败,不存在该用户", null);
} else {
Boolean flag = userInfoService.updateById(userInfo);
userInfoQuery = userInfoService.query().eq("user_id", userInfo.getUserId()).one();
if (flag) {
cos.deleteObject(userInfo.getUserAvatar());
return new ResponseData(200, "更新成功", userInfoQuery);
} else {
return new ResponseData(500, "更新失败", userInfoQuery);
}
}
}
此时文件上传成功,但是最后在UserInfoController中删除原来图片时报错403,如下:
com.qcloud.cos.exception.CosServiceException: The Signature you specified is invalid. (Status Code: 403; Error Code: SignatureDoesNotMatch; Request ID: NWNmNTAwODlfMjBiNDU4NjRfODMzZF8yNDUzZmVi); Trace ID: OGVmYzZiMmQzYjA2OWNhODk0NTRkMTBiOWVmMDAxODc0OWRkZjk0ZDM1NmI1M2E2MTRlY2MzZDhmNmI5MWI1OTQyYWVlY2QwZTk2MDVmZDQ3MmI2Y2I4ZmI5ZmM4ODFjYjdkMDE0YzdiNDU3MThiMzQ3NzBkMmQwZjE1ZWVlZmU=
at com.qcloud.cos.http.DefaultCosHttpClient.handlerErrorMessage(DefaultCosHttpClient.java:302) ~[cos_api-5.5.3.jar:na]
at com.qcloud.cos.http.DefaultCosHttpClient.exeute(DefaultCosHttpClient.java:402) ~[cos_api-5.5.3.jar:na]
at com.qcloud.cos.COSClient.invoke(COSClient.java:524) ~[cos_api-5.5.3.jar:na]
at com.qcloud.cos.COSClient.deleteObject(COSClient.java:1115) ~[cos_api-5.5.3.jar:na]
at com.qcloud.cos.COSClient.deleteObject(COSClient.java:1094) ~[cos_api-5.5.3.jar:na]
at com.wenqiuhan.mini.util.TencentCos.deleteObject(TencentCos.java:44) ~[classes/:na]
at com.wenqiuhan.mini.controller.UserInfoCommonController.updateUserAvatarByUserId(UserInfoCommonController.java:75) ~[classes/:na]
at com.wenqiuhan.mini.controller.UserInfoController.updateUserAvatarByUserId(UserInfoController.java:45) ~[classes/:na]
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[na:na]
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) ~[na:na]
at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) ~[na:na]
at java.base/java.lang.reflect.Method.invoke(Method.java:567) ~[na:na]
at org.springframework.web.method.support.InvocableHandlerMethod.doInvoke(InvocableHandlerMethod.java:190) ~[spring-web-5.1.7.RELEASE.jar:5.1.7.RELEASE]
at org.springframework.web.method.support.InvocableHandlerMethod.invokeForRequest(InvocableHandlerMethod.java:138) ~[spring-web-5.1.7.RELEASE.jar:5.1.7.RELEASE]
at org.springframework.web.servlet.mvc.method.annotation.ServletInvocableHandlerMethod.invokeAndHandle(ServletInvocableHandlerMethod.java:104) ~[spring-webmvc-5.1.7.RELEASE.jar:5.1.7.RELEASE]
at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.invokeHandlerMethod(RequestMappingHandlerAdapter.java:892) ~[spring-webmvc-5.1.7.RELEASE.jar:5.1.7.RELEASE]
at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.handleInternal(RequestMappingHandlerAdapter.java:797) ~[spring-webmvc-5.1.7.RELEASE.jar:5.1.7.RELEASE]
at org.springframework.web.servlet.mvc.method.AbstractHandlerMethodAdapter.handle(AbstractHandlerMethodAdapter.java:87) ~[spring-webmvc-5.1.7.RELEASE.jar:5.1.7.RELEASE]
at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:1039) ~[spring-webmvc-5.1.7.RELEASE.jar:5.1.7.RELEASE]
at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:942) ~[spring-webmvc-5.1.7.RELEASE.jar:5.1.7.RELEASE]
at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:1005) ~[spring-webmvc-5.1.7.RELEASE.jar:5.1.7.RELEASE]
at org.springframework.web.servlet.FrameworkServlet.doPost(FrameworkServlet.java:908) ~[spring-webmvc-5.1.7.RELEASE.jar:5.1.7.RELEASE]
at javax.servlet.http.HttpServlet.service(HttpServlet.java:660) ~[tomcat-embed-core-9.0.19.jar:9.0.19]
at org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:882) ~[spring-webmvc-5.1.7.RELEASE.jar:5.1.7.RELEASE]
at javax.servlet.http.HttpServlet.service(HttpServlet.java:741) ~[tomcat-embed-core-9.0.19.jar:9.0.19]
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:231) ~[tomcat-embed-core-9.0.19.jar:9.0.19]
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166) ~[tomcat-embed-core-9.0.19.jar:9.0.19]
at org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:53) ~[tomcat-embed-websocket-9.0.19.jar:9.0.19]
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193) ~[tomcat-embed-core-9.0.19.jar:9.0.19]
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166) ~[tomcat-embed-core-9.0.19.jar:9.0.19]
at org.springframework.web.filter.RequestContextFilter.doFilterInternal(RequestContextFilter.java:99) ~[spring-web-5.1.7.RELEASE.jar:5.1.7.RELEASE]
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107) ~[spring-web-5.1.7.RELEASE.jar:5.1.7.RELEASE]
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193) ~[tomcat-embed-core-9.0.19.jar:9.0.19]
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166) ~[tomcat-embed-core-9.0.19.jar:9.0.19]
at org.springframework.web.filter.FormContentFilter.doFilterInternal(FormContentFilter.java:92) ~[spring-web-5.1.7.RELEASE.jar:5.1.7.RELEASE]
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107) ~[spring-web-5.1.7.RELEASE.jar:5.1.7.RELEASE]
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193) ~[tomcat-embed-core-9.0.19.jar:9.0.19]
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166) ~[tomcat-embed-core-9.0.19.jar:9.0.19]
at org.springframework.web.filter.HiddenHttpMethodFilter.doFilterInternal(HiddenHttpMethodFilter.java:93) ~[spring-web-5.1.7.RELEASE.jar:5.1.7.RELEASE]
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107) ~[spring-web-5.1.7.RELEASE.jar:5.1.7.RELEASE]
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193) ~[tomcat-embed-core-9.0.19.jar:9.0.19]
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166) ~[tomcat-embed-core-9.0.19.jar:9.0.19]
at org.springframework.web.filter.CharacterEncodingFilter.doFilterInternal(CharacterEncodingFilter.java:200) ~[spring-web-5.1.7.RELEASE.jar:5.1.7.RELEASE]
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107) ~[spring-web-5.1.7.RELEASE.jar:5.1.7.RELEASE]
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193) ~[tomcat-embed-core-9.0.19.jar:9.0.19]
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166) ~[tomcat-embed-core-9.0.19.jar:9.0.19]
at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:200) ~[tomcat-embed-core-9.0.19.jar:9.0.19]
at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:96) ~[tomcat-embed-core-9.0.19.jar:9.0.19]
at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:490) ~[tomcat-embed-core-9.0.19.jar:9.0.19]
at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:139) ~[tomcat-embed-core-9.0.19.jar:9.0.19]
at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:92) ~[tomcat-embed-core-9.0.19.jar:9.0.19]
at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:74) ~[tomcat-embed-core-9.0.19.jar:9.0.19]
at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:343) ~[tomcat-embed-core-9.0.19.jar:9.0.19]
at org.apache.coyote.http11.Http11Processor.service(Http11Processor.java:408) ~[tomcat-embed-core-9.0.19.jar:9.0.19]
at org.apache.coyote.AbstractProcessorLight.process(AbstractProcessorLight.java:66) ~[tomcat-embed-core-9.0.19.jar:9.0.19]
at org.apache.coyote.AbstractProtocol$ConnectionHandler.process(AbstractProtocol.java:836) ~[tomcat-embed-core-9.0.19.jar:9.0.19]
at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1747) ~[tomcat-embed-core-9.0.19.jar:9.0.19]
at org.apache.tomcat.util.net.SocketProcessorBase.run(SocketProcessorBase.java:49) ~[tomcat-embed-core-9.0.19.jar:9.0.19]
at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1128) ~[na:na]
at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:628) ~[na:na]
at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61) ~[tomcat-embed-core-9.0.19.jar:9.0.19]
at java.base/java.lang.Thread.run(Thread.java:835) ~[na:na]
看报错显示签名错误,但着实不知道错在哪里,
或者实现该功能的正确做法是什么呢,多谢各位了,
相似问题