소스 검색

更新 /api/oss/sdk/presign 接口,添加一个 objectUrl 参数,可直接对 url 进行签名

reghao 1 개월 전
부모
커밋
c8b6366ab5

+ 4 - 2
oss-mgr/src/main/java/cn/reghao/oss/mgr/controller/OssSdkController.java

@@ -70,8 +70,10 @@ public class OssSdkController {
 
     @Operation(summary = "获取访问对象所需的签名 URL", description = "N")
     @GetMapping(value = "/presign", produces = MediaType.APPLICATION_JSON_VALUE)
-    public String getPresignedUrl(@RequestParam("objectId") String objectId, @RequestParam("action") String action) {
-        Result result = ossClientService.getSignedUrl(objectId, action);
+    public String getPresignedUrl(@RequestParam("objectId") String objectId,
+                                  @RequestParam("action") String action,
+                                  @RequestParam("objectUrl") String objectUrl) {
+        Result result = ossClientService.getSignedUrl(objectId, action, objectUrl);
         if (result.getCode() == ResultStatus.SUCCESS.getCode()) {
             return WebResult.success(result.getData());
         }

+ 54 - 8
oss-mgr/src/main/java/cn/reghao/oss/mgr/service/OssClientService.java

@@ -60,10 +60,14 @@ public class OssClientService {
         this.userKeyService = userKeyService;
     }
 
-    public Result getSignedUrl(String objectId, String action) {
+    public Result getSignedUrl(String objectId, String action, String objectUrl) {
+        if (objectUrl != null && !objectUrl.isBlank()) {
+            return getSignedUrl0(objectId, objectUrl);
+        }
+
         long loginUser = UserContext.getUserId();
-        ObjectMeta objectMeta = objectRepository.getObjectMetaById(objectId, loginUser);
-        if (objectMeta == null) {
+        objectUrl = getObjectUrl(objectId, loginUser);
+        if (objectUrl == null) {
             return Result.fail("Object not exist");
         }
 
@@ -84,30 +88,72 @@ public class OssClientService {
 
         // 3. 调用工具类生成签名
         String sign = SignatureUtils.calculateSignature(accessKeyId, expires, objectId);
+        String signedParams = String.format("ak=%s&t=%s&nonce=%s&sign=%s", accessKeyId, expires, nonce, sign);;
+
+        // 4. 拼接最终的公网访问 URL
+        // 格式:域名 + objectId + 参数
+        String signedUrl = String.format("%s?%s", objectUrl, signedParams);
+        Result result = Result.success(signedUrl);
+
+        Result result0 = getSignedUrl0(objectId, objectUrl);
+        return result0;
+    }
+
+    private String getObjectUrl(String objectId, long loginUser) {
+        ObjectMeta objectMeta = objectRepository.getObjectMetaById(objectId, loginUser);
+        if (objectMeta == null) {
+            //return Result.fail("Object not exist");
+            return null;
+        }
 
         String objectName = objectMeta.getObjectName();
         UploadChannel uploadChannel = getUploadChannel(loginUser, objectName);
         if (uploadChannel == null) {
-            return Result.fail("UploadChannel not found");
+            //return Result.fail("UploadChannel not found");
+            return null;
         }
 
         int userNodeId = uploadChannel.getUserNodeId();
         UserNode userNode = userNodeService.getUserNode(userNodeId);
         if (userNode == null) {
-            return Result.fail("UserNode not found");
+            //return Result.fail("UserNode not found");
+            return null;
         }
-
         String protocol = userNode.getProtocol();
         String domain = userNode.getDomain();
-        String ossUrl = String.format("%s://%s", protocol, domain);
+        String objectUrl = String.format("%s://%s/%s", protocol, domain, objectName);
+        return objectUrl;
+    }
+
+    private Result getSignedUrl0(String objectId, String objectUrl) {
+        long loginUser = UserContext.getUserId();
+        // 24h
+        int durationInMinutes = 1440;
+        // 2. 计算过期时间(当前时间 + 持续分钟数)
+        long expires = (System.currentTimeMillis() / 1000) + (durationInMinutes * 60L);
+
+        UserKey userKey = userKeyService.getUserKey(loginUser);
+        if (userKey == null) {
+            return Result.fail("UserKey not exist");
+        }
+        String accessKeyId = userKey.getAccessKeyId();
+
+        // 生成一个短随机数,例如 UUID 的前 8 位或随机 16 进制字符串
+        // 避免重放攻击, 使 url 只能访问一次
+        String nonce = UUID.randomUUID().toString().substring(0, 8);
+
+        // 3. 调用工具类生成签名
+        String sign = SignatureUtils.calculateSignature(accessKeyId, expires, objectId);
         String signedParams = String.format("ak=%s&t=%s&nonce=%s&sign=%s", accessKeyId, expires, nonce, sign);;
 
         // 4. 拼接最终的公网访问 URL
         // 格式:域名 + objectId + 参数
-        String signedUrl = String.format("%s/%s?%s", ossUrl, objectName, signedParams);
+        String signedUrl = String.format("%s?%s", objectUrl, signedParams);
         return Result.success(signedUrl);
     }
 
+
+
     private UploadChannel getUploadChannel(long loginUser, String objectName) {
         List<UploadChannel> uploadChannelList = uploadChannelService.getUploadChannelsByCreateBy(loginUser);
         Collections.reverse(uploadChannelList);

+ 2 - 3
oss-sdk/src/main/java/cn/reghao/oss/sdk/OssClient.java

@@ -3,7 +3,6 @@ package cn.reghao.oss.sdk;
 import cn.reghao.jutil.jdk.io.FileSplitter;
 import cn.reghao.jutil.jdk.serializer.JsonConverter;
 import cn.reghao.jutil.jdk.web.result.WebResult;
-import cn.reghao.oss.api.constant.ObjectScope;
 import cn.reghao.oss.api.dto.*;
 import cn.reghao.oss.api.dto.media.VideoInfo;
 import cn.reghao.oss.api.dto.rest.UploadFileRet;
@@ -309,8 +308,8 @@ public class OssClient {
         return null;
     }
 
-    public String getSignedUrl(String objectId, String action) throws Exception {
-        String queryString = String.format("objectId=%s&action=%s", objectId, action);
+    public String getSignedUrl(String objectId, String action, String objectUrl) throws Exception {
+        String queryString = String.format("objectId=%s&action=%s&objectUrl=%s", objectId, action);
         String api = "/api/oss/sdk/presign";
         String url = String.format("%s%s?%s", endpoint, api, queryString);
 

+ 1 - 1
oss-sdk/src/test/java/OssClientTest.java

@@ -81,7 +81,7 @@ public class OssClientTest {
         UploadFileRet uploadFileRet = ossClient.postObject(101, file);
 
         String objectId = "653ee234e1964cfda3578efbe1e7d0b0";
-        String signedUrl = ossClient.getSignedUrl(objectId, ObjectAction.access.getName());
+        String signedUrl = ossClient.getSignedUrl(objectId, ObjectAction.access.getName(), null);
         System.out.printf("signed url -> %s\n", signedUrl);
     }
 }