|
|
@@ -1,10 +1,18 @@
|
|
|
package cn.reghao.dfs.store.controller;
|
|
|
|
|
|
import cn.reghao.dfs.store.service.GetObjectService;
|
|
|
+import cn.reghao.dfs.store.util.JwtUtil;
|
|
|
import cn.reghao.dfs.store.util.ObjectUtil;
|
|
|
+import cn.reghao.dfs.store.util.SignatureUtil;
|
|
|
+import cn.reghao.oss.api.constant.UploadChannel;
|
|
|
+import cn.reghao.oss.api.dto.OssPayload;
|
|
|
+import com.github.benmanes.caffeine.cache.Cache;
|
|
|
+import com.github.benmanes.caffeine.cache.Caffeine;
|
|
|
import org.springframework.web.bind.annotation.*;
|
|
|
|
|
|
+import javax.servlet.http.HttpServletResponse;
|
|
|
import java.io.IOException;
|
|
|
+import java.util.concurrent.TimeUnit;
|
|
|
|
|
|
/**
|
|
|
* @author reghao
|
|
|
@@ -13,9 +21,11 @@ import java.io.IOException;
|
|
|
@RestController
|
|
|
public class ObjectGetController {
|
|
|
private final GetObjectService getObjectService;
|
|
|
+ private final Cache<String, String> cache;
|
|
|
|
|
|
public ObjectGetController(GetObjectService getObjectService) {
|
|
|
this.getObjectService = getObjectService;
|
|
|
+ this.cache = Caffeine.newBuilder().maximumSize(10_000).expireAfterAccess(1, TimeUnit.HOURS).build();
|
|
|
}
|
|
|
|
|
|
@RequestMapping(value = "/**", method = RequestMethod.HEAD)
|
|
|
@@ -25,12 +35,63 @@ public class ObjectGetController {
|
|
|
}
|
|
|
|
|
|
@GetMapping(value = "/**")
|
|
|
- public void getObject(@RequestParam(value = "download", required = false) String download) throws IOException {
|
|
|
+ public void getObject(@RequestParam(value = "token", required = false) String token,
|
|
|
+ @RequestParam(value = "t", required = false) Long timestamp,
|
|
|
+ @RequestParam(value = "nonce", required = false) String nonce,
|
|
|
+ @RequestParam(value = "sign", required = false) String sign,
|
|
|
+ @RequestParam(value = "client", required = false) String client) throws IOException {
|
|
|
String objectName = ObjectUtil.getObjectName();
|
|
|
- if (download == null) {
|
|
|
+ if (client != null && !client.isBlank()) {
|
|
|
getObjectService.getObject(objectName);
|
|
|
+ return;
|
|
|
+ }
|
|
|
+
|
|
|
+ if (objectName.startsWith(UploadChannel.avatar.getPrefix()) ||
|
|
|
+ objectName.startsWith(UploadChannel.image.getPrefix())) {
|
|
|
+ getObjectService.getObject(objectName);
|
|
|
+ return;
|
|
|
+ }
|
|
|
+
|
|
|
+ String queryString = String.format("token=%s&t=%s&nonce=%s", token, timestamp, nonce);
|
|
|
+ String url = String.format("%s/%s", "//oss.reghao.cn", objectName);
|
|
|
+ String requestString = String.format("%s%s?%s", "GET", url, queryString);
|
|
|
+ String secretKey = "oss.reghao.cn";
|
|
|
+ boolean valid = SignatureUtil.valid(requestString, secretKey, sign);
|
|
|
+ if (!valid) {
|
|
|
+ getObjectService.writeResponse(HttpServletResponse.SC_FORBIDDEN);
|
|
|
+ return;
|
|
|
+ }
|
|
|
+
|
|
|
+ long current = System.currentTimeMillis();
|
|
|
+ if (current > timestamp) {
|
|
|
+ getObjectService.writeResponse(HttpServletResponse.SC_FORBIDDEN);
|
|
|
+ return;
|
|
|
+ }
|
|
|
+
|
|
|
+ /*String value = cache.getIfPresent(nonce);
|
|
|
+ if (value == null) {
|
|
|
+ cache.put(nonce, nonce);
|
|
|
} else {
|
|
|
+ getObjectService.writeResponse(HttpServletResponse.SC_FORBIDDEN);
|
|
|
+ return;
|
|
|
+ }*/
|
|
|
+
|
|
|
+ OssPayload ossPayload = JwtUtil.getOssPayload(token);
|
|
|
+ int channelId = ossPayload.getChannelId();
|
|
|
+ long userId = ossPayload.getUserId();
|
|
|
+ String prefix = UploadChannel.getUploadChannel(channelId).getPrefix();
|
|
|
+ if (!objectName.startsWith(prefix)) {
|
|
|
+ getObjectService.writeResponse(HttpServletResponse.SC_FORBIDDEN);
|
|
|
+ return;
|
|
|
+ }
|
|
|
+
|
|
|
+ String action = ossPayload.getAction();
|
|
|
+ if ("access".equals(action)) {
|
|
|
+ getObjectService.getObject(objectName);
|
|
|
+ } else if ("download".equals(action)) {
|
|
|
getObjectService.downloadObject(objectName);
|
|
|
+ } else {
|
|
|
+ getObjectService.writeResponse(HttpServletResponse.SC_FORBIDDEN);
|
|
|
}
|
|
|
}
|
|
|
}
|