Skip to content

Commit 3bb604b

Browse files
authored
#446 [Merge] dev 변경사항을 main에 반영 (v2.0.37)
1 parent 4c22ee5 commit 3bb604b

6 files changed

Lines changed: 48 additions & 12 deletions

File tree

‎src/main/java/com/swyp/picke/domain/oauth/jwt/JwtFilter.java‎

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -39,8 +39,9 @@ public class JwtFilter extends OncePerRequestFilter {
3939
"/favicon.ico",
4040
"/api/v1/auth/login",
4141
"/api/v1/auth/refresh",
42-
"/swagger-ui",
43-
"/v3/api-docs",
42+
"/swagger-ui",
43+
"/v3/api-docs",
44+
"/webjars",
4445
"/api/v1/home",
4546
"/api/v1/notices",
4647
"/api/test",

‎src/main/java/com/swyp/picke/global/config/S3Config.java‎

Lines changed: 16 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -6,21 +6,34 @@
66
import software.amazon.awssdk.auth.credentials.AwsBasicCredentials;
77
import software.amazon.awssdk.auth.credentials.StaticCredentialsProvider;
88
import software.amazon.awssdk.regions.Region;
9+
import software.amazon.awssdk.services.s3.S3Configuration;
910
import software.amazon.awssdk.services.s3.presigner.S3Presigner;
1011

12+
import java.net.URI;
13+
1114
@Configuration
1215
public class S3Config {
1316

1417
@Bean
1518
public S3Presigner s3Presigner(
1619
@Value("${spring.cloud.aws.region.static}") String region,
1720
@Value("${spring.cloud.aws.credentials.access-key}") String accessKey,
18-
@Value("${spring.cloud.aws.credentials.secret-key}") String secretKey) {
21+
@Value("${spring.cloud.aws.credentials.secret-key}") String secretKey,
22+
@Value("${spring.cloud.aws.s3.endpoint:}") String endpoint,
23+
@Value("${spring.cloud.aws.s3.path-style-access-enabled:false}") boolean pathStyleAccessEnabled) {
1924

20-
return S3Presigner.builder()
25+
S3Presigner.Builder builder = S3Presigner.builder()
2126
.region(Region.of(region))
2227
.credentialsProvider(StaticCredentialsProvider.create(
2328
AwsBasicCredentials.create(accessKey, secretKey)))
24-
.build();
29+
.serviceConfiguration(S3Configuration.builder()
30+
.pathStyleAccessEnabled(pathStyleAccessEnabled)
31+
.build());
32+
33+
if (!endpoint.isBlank()) {
34+
builder.endpointOverride(URI.create(endpoint));
35+
}
36+
37+
return builder.build();
2538
}
2639
}

‎src/main/java/com/swyp/picke/global/config/SecurityConfig.java‎

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,7 @@ public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
4444
"/api/v1/notices/**",
4545
"/api/test/**",
4646
"/swagger-ui/**", "/swagger-ui.html", "/v3/api-docs/**",
47+
"/webjars/**",
4748
"/js/**", "/css/**", "/favicon.ico",
4849
"/api/v1/admin/login", "/api/v1/admin",
4950
"/result/**",

‎src/main/java/com/swyp/picke/global/infra/s3/service/S3PresignedUrlService.java‎

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
import software.amazon.awssdk.services.s3.presigner.S3Presigner;
88
import software.amazon.awssdk.services.s3.presigner.model.GetObjectPresignRequest;
99

10+
import java.net.URI;
1011
import java.time.Duration;
1112
import java.util.Map;
1213
import java.util.stream.Collectors;
@@ -54,11 +55,16 @@ public <K> Map<K, String> generatePresignedUrls(Map<K, String> keyMap) {
5455
));
5556
}
5657

58+
/**
59+
* DB에는 보통 순수 key만 저장되지만, AWS S3를 쓰던 시절 저장된 레거시 데이터는
60+
* 전체 URL(https://{bucket}.s3.{region}.amazonaws.com/{key})일 수 있어 하위 호환을 위해 파싱한다.
61+
* 스토리지 제공자(AWS/Railway 등)에 무관하게 동작하도록 호스트가 아닌 경로 기준으로 key를 뽑는다.
62+
*/
5763
private String extractKey(String input) {
58-
if (input.startsWith("https://") && input.contains(".s3.") && input.contains(".amazonaws.com/")) {
59-
int idx = input.indexOf(".amazonaws.com/") + ".amazonaws.com/".length();
60-
return input.substring(idx);
64+
if (!input.startsWith("http://") && !input.startsWith("https://")) {
65+
return input;
6166
}
62-
return input;
67+
String path = URI.create(input).getPath();
68+
return path.startsWith("/") ? path.substring(1) : path;
6369
}
6470
}

‎src/main/java/com/swyp/picke/global/infra/s3/service/S3UploadServiceImpl.java‎

Lines changed: 16 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515
import software.amazon.awssdk.services.s3.presigner.model.GetObjectPresignRequest;
1616

1717
import java.io.File;
18+
import java.net.URI;
1819
import java.nio.file.Files;
1920
import java.nio.file.Path;
2021
import java.time.Duration;
@@ -78,7 +79,7 @@ public File downloadFile(String fileUrl) {
7879

7980
try {
8081
// URL에서 순수 Key만 추출
81-
String pureKey = fileUrl.contains(".com/") ? fileUrl.split(".com/")[1] : fileUrl;
82+
String pureKey = extractKey(fileUrl);
8283

8384
// 다운로드 받을 로컬 임시 파일 경로 생성
8485
File tempFile = File.createTempFile("s3_download_", ".mp3");
@@ -112,7 +113,7 @@ public String getPresignedUrl(String key, Duration durationUrl) {
112113
if (key == null || key.isEmpty()) return null;
113114

114115
// URL에서 도메인을 제외한 순수 'Key'만 추출 (만약 전체 URL이 들어올 경우를 대비)
115-
String pureKey = key.contains(".com/") ? key.split(".com/")[1] : key;
116+
String pureKey = extractKey(key);
116117

117118
GetObjectPresignRequest presignRequest = GetObjectPresignRequest.builder()
118119
.signatureDuration(durationUrl)
@@ -122,6 +123,18 @@ public String getPresignedUrl(String key, Duration durationUrl) {
122123
return s3Presigner.presignGetObject(presignRequest).url().toString();
123124
}
124125

126+
/**
127+
* DB/외부 입력에는 순수 key가 오는 게 기본이지만, 레거시 데이터나 실수로 전체 URL이
128+
* 들어오는 경우를 대비해 호스트가 아닌 경로 기준으로 key를 추출한다(스토리지 제공자 무관).
129+
*/
130+
private String extractKey(String input) {
131+
if (!input.startsWith("http://") && !input.startsWith("https://")) {
132+
return input;
133+
}
134+
String path = URI.create(input).getPath();
135+
return path.startsWith("/") ? path.substring(1) : path;
136+
}
137+
125138
private String determineContentType(String key) {
126139
if (key.endsWith(".mp3")) return "audio/mpeg";
127140
if (key.endsWith(".png")) return "image/png";
@@ -149,7 +162,7 @@ public void deleteFile(String fileUrl) {
149162

150163
try {
151164
// 1. 전체 URL에서 순수 Key 추출 (기존 getPresignedUrl에 있던 방식과 동일하게 처리)
152-
String pureKey = fileUrl.contains(".com/") ? fileUrl.split(".com/")[1] : fileUrl;
165+
String pureKey = extractKey(fileUrl);
153166

154167
// 2. AWS SDK v2 전용 삭제 요청 객체 생성
155168
DeleteObjectRequest deleteObjectRequest = DeleteObjectRequest.builder()

‎src/main/resources/application.yml‎

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,8 @@ spring:
3232
aws:
3333
s3:
3434
bucket: ${AWS_S3_BUCKET}
35+
endpoint: ${AWS_ENDPOINT_URL:}
36+
path-style-access-enabled: ${S3_PATH_STYLE_ACCESS_ENABLED:false}
3537
region:
3638
static: ${AWS_REGION}
3739
credentials:

0 commit comments

Comments
 (0)