腾讯云cos web直传相关问题?

  • 回答 (2)
  • 关注 (0)
  • 查看 (218)

前台使用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]

看报错显示签名错误,但着实不知道错在哪里,

或者实现该功能的正确做法是什么呢,多谢各位了,

闻秋寒闻秋寒提问于
闻秋寒回答于

@楼上 用户1279759:

昂昂,这个get错了,应该get数据库里面的,我改过来了,但是权限问题还是存在,

用户1279759回答于

你getUserAvatar()的值好奇怪,建议检查一下

所属标签

可能回答问题的人

  • 波斯狗儿

    5 粉丝0 提问28 回答
  • galenye

    腾讯 · 工程师 (已认证)

    5 粉丝0 提问36 回答
  • Jinqn

    腾讯 · 高级工程师 (已认证)

    16 粉丝0 提问58 回答
  • 腾讯云技术服务团队

    腾讯云 · 技术服务团队 (已认证)

    21 粉丝0 提问3 回答
  • 宝哥@devops运维

    腾讯 · 高级云计算工程师 (已认证)

    64 粉丝0 提问0 回答
  • elliswu

    腾讯计算机系统有限公司 · 高级工程师 (已认证)

    4 粉丝0 提问0 回答

扫码关注云+社区

领取腾讯云代金券