지난 포스팅에서 Presigned url을 발급 받아보았다.
https://suloth.tistory.com/188
이번 포스팅에서는 발급받은 presigned url에 대한 후처리 (DB에 profileUrl 업로드) 작업에 대해 포스팅하려고 한다.
왜 presigned url을 이용해서 이미지를 S3에 PUT 했는데, 또 처리가 필요하냐고 묻는다면
다음과 같은 이유가 있다.
1. DB를 업데이트 해줘야 한다.
- S3에 업로드만 하면 뭐하나. DB의 profileUrl을 업데이트 해줘야 나중에 해당 url로 이미지를 가져올 수 있다.
2. 아니 그러면, presigned url 발급 받을 때 DB 업데이트 하면 되지않나?
- 말도 안되는 소리다. url 발급 받을 때 DB를 업데이트 해버리면, 모종의 이유로 presigned url을 사용해서 이미지를 업로드할 때 에러가 발생하거나, 발급받은 presigned url을 사용하지 않는 경우에는 해당 파일 url은 아무것도 없는 url이 되어버린다.
위 두 가지 이유 때문에 S3에 이미지 업로드 후, 클라이언트에서 서버측으로 업로드 완료 요청을 보내는 것이다.
Presigned url을 이용한 업로드 완료 요청
먼저, presigned url을 발급받으면 중간에 저장될 파일명을 찾을 수 있다.
https://버킷명.s3.리전.amazonaws.com/1702984544757abc.jpeg
?X-Amz-Algorithm=AWS4-HMAC-SHA256
&X-Amz-Content-Sha256=UNSIGNED-PAYLOAD
&X-Amz-Credential=임의의값
&X-Amz-Date=20231219T111544Z
&X-Amz-Expires=180
&X-Amz-Signature=임의의값
&X-Amz-SignedHeaders=host
&x-id=PutObject
위 url에서 https://버킷명.s3.리전.amazonws.com/1702984544757abc.jpeg
가 해당 파일을 얻을 수 있는 url이다.
따라서, 클라이언트 측에서는 presigned url의 해당 부분을 가지고 서버에게 요청을 보내면 된다.
먼저, body로 받을 Dto를 정의하자.
profileImageUrl이 필요하다.
// update-user-profile-image.dto.ts
// class-validator를 사용하는 경우
export class UpdateUserProfileImageDto extends PickType(UserEntity, [
'profileImgUrl',
] as const) {}
// 혹은
interface UpdateUserProfileImageDto {
profileImgUrl: string;
}
그리고 Controller와 Service를 작성하자.
이미지 프로필에 대한 수정 요청이므로 Put메소드를 사용한다.
여기서는 JWT를 통한 로그인을 고려하고 작성한다.
// user.controller.ts
@UseGuards(AccessTokenAuthGuard)
@Put('profile-image')
async updateUserProfileImage(
@Body() body: UpdateUserProfileImageDto,
): Promise<boolean> {
const isUpdated = await this.userService.updateUserProfileImage(
body,
user.id,
);
return isUpdated;
}
// user.service.ts
async updateUserProfileImage(
updateUserProfileImageDto: UpdateUserProfileImageDto,
userId: number,
): Promise<boolean> {
const isUpdated = await this.userRepository.updateUser(
{
profileImgUrl: updateUserProfileImageDto.profileImgUrl,
},
{
id: userId,
},
);
return isUpdated;
}
이런식으로 작성하면 된다.
나의 경우에는 update가 되면, true를 리턴하도록 Repository에 updateUser함수를 만들어서 짜놨다.
userId에 해당하는 user의 profileImgUrl을 수정하도록 작성했다.
어차피 로그인을 해야 업데이트할 수 있게 해놨으므로 따로 이상한 값으로 요청을 보낼 수 없다고 생각했으므로 url 검증은 하지 않았다.
하지만, 만약에 url 검증이 필요하다면 redis같은 cache db를 두거나, url암호화를 통한 검증을 하면 될 것 같다.
혹시, 이 방법보다 좋은 방법을 알고 있으시다면 댓글 부탁드립니다.
'Back-end > nest.js' 카테고리의 다른 글
Nest.js : AWS S3 Presigned url 사용하기 - 1 (0) | 2023.12.19 |
---|---|
Nest.js : Nestia에서 SDK 배포하는 법 (0) | 2023.08.13 |
Nest.js : gRPC 통신 (+Python gRPC) (0) | 2023.07.25 |
#1. Nestia : 네스티아를 배워보자 - 초기 설정 (0) | 2023.07.02 |
Nest.js : Controller url 오류 (컨트롤러 경로 오류, 에러) (0) | 2023.06.19 |