diff --git a/src/main/java/com/jiaruiblog/config/WebMvcConfig.java b/src/main/java/com/jiaruiblog/config/WebMvcConfig.java index ef6be71..4df1516 100644 --- a/src/main/java/com/jiaruiblog/config/WebMvcConfig.java +++ b/src/main/java/com/jiaruiblog/config/WebMvcConfig.java @@ -4,6 +4,7 @@ import com.jiaruiblog.util.converter.StringCodeToEnumConverterFactory; import org.springframework.context.annotation.Configuration; import org.springframework.format.FormatterRegistry; +import org.springframework.web.servlet.config.annotation.CorsRegistry; import org.springframework.web.servlet.config.annotation.WebMvcConfigurer; /** @@ -25,5 +26,15 @@ public void addFormatters(FormatterRegistry registry) { registry.addConverterFactory(new StringCodeToEnumConverterFactory()); } - + /** + * CORS 配置,允许前端访问 Content-Disposition 头部信息 + */ + @Override + public void addCorsMappings(CorsRegistry registry) { + registry.addMapping("/**") + .allowedOrigins("*") // 根据需要调整允许的前端域名 + .allowedMethods("GET", "POST", "PUT", "DELETE") + .allowedHeaders("*") + .exposedHeaders("Content-Disposition"); // 允许前端访问 Content-Disposition + } } diff --git a/src/main/java/com/jiaruiblog/controller/FileController.java b/src/main/java/com/jiaruiblog/controller/FileController.java index ed41ebd..42610d8 100644 --- a/src/main/java/com/jiaruiblog/controller/FileController.java +++ b/src/main/java/com/jiaruiblog/controller/FileController.java @@ -46,7 +46,6 @@ import javax.servlet.http.HttpServletResponse; import java.io.*; import java.net.URLEncoder; -import java.nio.charset.StandardCharsets; import java.time.Duration; import java.util.*; import java.util.regex.Matcher; @@ -173,12 +172,8 @@ public BaseApiResult generateDownloadLink(@RequestParam String fileId, // 使用hmacKey作为Redis的key,存储fileId,设置短时有效期 redisTemplate.opsForValue().set(hmacKey, fileId, Duration.ofMinutes(10)); - - // URL Encode HMAC - String encodedHmac = URLEncoder.encode(hmacKey, StandardCharsets.UTF_8.toString()); - // 返回下载链接 - return BaseApiResult.success(encodedHmac); + return BaseApiResult.success(hmacKey); } /* @@ -205,8 +200,9 @@ public ResponseEntity downloadFile(@RequestParam String fileI FileDocument fileDocument = file.get(); return ResponseEntity.ok() + .header(HttpHeaders.CONTENT_DISPOSITION, + "attachment; fileName=" + URLEncoder.encode(fileDocument.getName(), "utf-8")) .contentType(MediaType.parseMediaType(fileDocument.getContentType())) - .header(HttpHeaders.CONTENT_DISPOSITION, "attachment; filename=\"" + fileDocument.getName() + "\"") .body(new ByteArrayResource(fileDocument.getContent())); } else { return ResponseEntity.status(HttpStatus.FORBIDDEN).build(); diff --git a/src/main/java/com/jiaruiblog/filter/JwtFilter.java b/src/main/java/com/jiaruiblog/filter/JwtFilter.java index e7f870c..c6e3d78 100644 --- a/src/main/java/com/jiaruiblog/filter/JwtFilter.java +++ b/src/main/java/com/jiaruiblog/filter/JwtFilter.java @@ -41,6 +41,10 @@ public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain) final HttpServletRequest request = (HttpServletRequest) req; final HttpServletResponse response = (HttpServletResponse) res; + // 在响应中添加必要的头部信息 + response.setHeader("Access-Control-Expose-Headers", "Content-Disposition"); + + response.setCharacterEncoding("UTF-8"); String url = request.getRequestURI().substring(request.getContextPath().length()); // 登录和注册等请求不需要令牌 diff --git a/src/main/java/com/jiaruiblog/util/HmacUtil.java b/src/main/java/com/jiaruiblog/util/HmacUtil.java index ae3af9f..fdef472 100644 --- a/src/main/java/com/jiaruiblog/util/HmacUtil.java +++ b/src/main/java/com/jiaruiblog/util/HmacUtil.java @@ -17,8 +17,10 @@ public String generateHmac(String data) throws Exception { Mac mac = Mac.getInstance("HmacSHA256"); SecretKeySpec secretKeySpec = new SecretKeySpec(secretKey.getBytes(), "HmacSHA256"); mac.init(secretKeySpec); - byte[] hmacData = mac.doFinal(data.getBytes()); - return Base64.getEncoder().encodeToString(hmacData); + byte[] hmacBytes = mac.doFinal(data.getBytes()); + + // 使用Base64进行URL安全的编码,生成的 hmac 是 URL 安全的,不会包含 `+`, `/` 或 `=` + return Base64.getUrlEncoder().withoutPadding().encodeToString(hmacBytes); } public boolean validateHmac(String data, String hmac) throws Exception {