[241223] AWS S3 ๊ถํ ๋ฌธ์ ๋ฐ ๋ฐ์ดํฐ ๋ฌด๊ฒฐ์ฑ, ์ค๋ณต ๋ฐ์ดํฐ ์ด์
์ด๋ฒ ํ๋ก์ ํธ ์ด๋ฆ์ "owner"๋ก ์ ํ๋ค.
Owner ํ๋ก์ ํธ๋ Owner๋ผ๋ฉด ๋ฐ๋์ ์์์ผ ํ๋ ์ ํ๋ฆฌ์ผ์ด์ ์ด๋ผ๋ ์ปจ์ ์ผ๋ก ์งํ๋์๋ค.
์ด ์ ํ๋ฆฌ์ผ์ด์ ์ To-Do-List๋ฅผ ํตํด ์์ ํํฉ์ ํ๋์ ํ์ ํ๊ณ , ์ฐธ์ฌ ์ธ์ ๊ฐ์ ํ๋ฐํ ์ํต๊ณผ ํจ๊ณผ์ ์ธ ์ผ์ ๊ด๋ฆฌ๊ฐ ๊ฐ๋ฅํ๋ค๋ ์ฅ์ ์ด ์๋ค!
ํ์ง๋ง ๊ฐ๋ฐ ๋์ค ๋ฌธ์ ๊ฐ ๋ฐ์ํ๊ณ ๊ทธ ๋ฌธ์ ์ ๋ํ ํด๊ฒฐ ๊ณผ์ ์ ์ ๋ฆฌํ๋ ค๊ณ ํ๋ค.
AWS S3 ๊ถํ ๊ด๋ จ ํธ๋ฌ๋ธ ์ํ
1. ๋ฌธ์ ์ํฉ
๐ ๋ณด๋ ์์ฑ ์์ฒญ ์, S3์ ์ฐ๋๋ backgroundImageUrl์ ์ ๊ทผํ ์ ์๋ ๋ฌธ์ ๋ฐ์
- S3 URL๋ก ์ด๋ฏธ์ง ์ ์ํ๋ฉด "์ ๊ทผ ๊ถํ ์์" ์๋ฌ๊ฐ ๋ฐํ๋จ.
2. ์์ธ ๋ถ์
1) Block Public Access ํ์ฑํ
- S3 Bucket ์ค์ ์์ Block Public Access ์ต์ ์ด ํ์ฑํ๋์ด ์ธ๋ถ์์ ์ ๊ทผ์ด ์ฐจ๋จ๋ ์ํ์๋ค.
2) Bucket Policy ๋ฏธ์ค์
- S3 Bucket์ ํ์ํ ์ ์ฑ (Bucket Policy)์ด ์ค์ ๋์ง ์์, ์ธ๋ถ ์์ฒญ์ด ์ ๋๋ก ์ฒ๋ฆฌ๋์ง ์์ ๋ฌธ์ ๊ฐ ์์๋ค.
3. ํด๊ฒฐ๋ฐฉ์
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "PublicRead",
"Effect": "Allow",
"Principal": "*",
"Action": "s3:GetObject",
"Resource": "arn:aws:s3:::bucket-name/*"
}
]
}
4. ๊ฒฐ๊ณผ
โก๏ธ ํ์ฌ ๋ชจ๋ ์ฌ์ฉ์๊ฐ ์ ๊ทผ ๊ฐ๋ฅํ๋๋ก ์ค์ ๋์ด ์์ง๋ง ํ์์ ํน์ ์ฌ์ฉ์๋ IP๋ง ์ ๊ทผํ ์ ์๋ ์ ์ฑ ์ ์ถ๊ฐํ ์ ์๋๋ก ์งํํ๊ณ ์ ํ๋ค.
๋ฐ์ดํฐ ๋ฌด๊ฒฐ์ฑ๊ณผ ์ค๋ณต ๋ฐ์ดํฐ ๋ฌธ์
1. ๋ฌธ์ ์ํฉ
๐ ๋ฆฌ์คํธ ์์ฑ ์ค IncorrectResultSizeDataAccessException ์๋ฌ ๋ฐ์
- ๋ฆฌ์คํธ ์์ฑ ์ค findByUserIdAndWorkspaceId ๋ฉ์๋ ํธ์ถ ์, Query did not return a unique result: 2 results were returned ์๋ฌ ๋ฐ์.
- ๋์ผํ user_id์ workspace_id ์กฐํฉ์ผ๋ก ์ฌ๋ฌ ๋ฉค๋ฒ ๋ฐ์ดํฐ๊ฐ ์กด์ฌํ๋ฉฐ, role ๊ฐ("BOARD", "READ")์ด ๋ค๋ฅธ ๋ฐ์ดํฐ๋ค์ด ์ค๋ณต๋์ด ์ฟผ๋ฆฌ์์ ๋ ๊ฐ ์ด์์ ๊ฒฐ๊ณผ๋ฅผ ๋ฐํ.
2. ์์ธ ๋ถ์
1) ์ค๋ณต๋ ๋ฐ์ดํฐ
- ๋ฐ์ดํฐ๋ฒ ์ด์ค์ ๋์ผํ user_id์ workspace_id๋ฅผ ๊ฐ์ง๋ ๋ฉค๋ฒ๊ฐ ์ฌ๋ฌ ๊ฐ ์กด์ฌํ๋ค.
- role ๊ฐ("BOARD", "READ")์ด ๋ค๋ฅด์ง๋ง ์ฟผ๋ฆฌ๊ฐ ์กฐ๊ฑด์ ๋ช ํํ ํ์ง ์์ ๋ค์์ ๊ฒฐ๊ณผ๋ฅผ ๋ฐํ๋ ๋ฏํ๋ค.
2) ์ฟผ๋ฆฌ ์ค๊ณ ๋ฌธ์
- findByUserIdAndWorkspaceId ๋ฉ์๋๊ฐ ๋จ์ผ ๊ฒฐ๊ณผ๋ฅผ ๋ฐํํด์ผ ํ๋ ์ํฉ์์ ์กฐ๊ฑด ์์ด ์ฌ๋ฌ ๊ฒฐ๊ณผ๋ฅผ ๊ฐ์ ธ์๋ค.
- // ๋ณ๊ฒฝ ์ Optional<Member> findByUserIdAndWorkspaceId(Long userId, Long workspaceId);
3) ๋ฐ์ดํฐ ๋ฌด๊ฒฐ์ฑ ๋ฌธ์
- user_id์ workspace_id์ ์กฐํฉ์ ๋ํด ์ ์ผ์ฑ์ ๋ณด์ฅํ์ง ์์ ๋ฐ์ดํฐ๊ฐ ์ค๋ณต ์ ์ฅ๋์๋ค.
3. ํด๊ฒฐ๋ฐฉ์
1) ์ฟผ๋ฆฌ ์์
- ์๋ก์ด ์ฟผ๋ฆฌ ๋ฉ์๋ findByUserIdAndWorkspaceIdAndRole๋ฅผ ์ถ๊ฐํ์ฌ ์ค๋ณต ๋ฐ์ดํฐ๋ฅผ ์ฒ๋ฆฌํ๊ณ , ํน์ role ๊ฐ๋ง ๋ฐํํ๋๋ก Query๋ฌธ์ผ๋ก ์์ฑํ๋ค.
// ๋ณ๊ฒฝ ํ
@Query("SELECT m FROM Member m WHERE m.user.id = :userId AND m.workspace.id = :workspaceId AND m.role = 'BOARD'")
Optional<Member> findByUserIdAndWorkspaceIdAndRole(@Param("userId") Long userId, @Param("workspaceId") Long workspaceId);
** role = 'BOARD'์ธ ๋ฐ์ดํฐ๋ง ์กฐํํ๋ฏ๋ก, ์ค๋ณต๋ ๋ฐ์ดํฐ๊ฐ ์๋๋ผ๋ ๋จ์ผ ๊ฒฐ๊ณผ('BOARD') ๊ฐ๋ง ๋ฐํ๋๋ค.
2) List Service ์ฝ๋ ์์
- ๊ธฐ์กด findByUserIdAndWorkspaceId ๋ฉ์๋๋ฅผ findByUserIdAndWorkspaceIdAndRole๋ก ์์ ํ์ฌ, ํน์ role์ ๊ฐ์ง ๋ฐ์ดํฐ๋ฅผ ๊ฐ์ ธ์ค๋๋ก ์์ ํ๋ค.
// ํน์ ๋ฉค๋ฒ ๋ถ๋ฌ์ค๊ธฐ
Member findMember = memberRepository.findByUserIdAndWorkspaceIdAndRole(user.getId(),requestDto.getWorkspaceId())
.orElseThrow(()-> new CustomException(ErrorCode.MEMBER_NOT_FOUND));
// ํน์ ๋ฉค๋ฒ role ๊ถํ ํ์ธ
if (!findMember.getRole().equals(MemberRole.BOARD)) {
throw new CustomException(ErrorCode.UNAUTHORIZED_ACCESS);
}
4. ๊ฒฐ๊ณผ
๐ ๋ฐ์ดํฐ๋ฒ ์ด์ค์ ๋์ผํ user_id์ workspace_id๋ฅผ ๊ฐ์ง๋ ๋ฉค๋ฒ๊ฐ ์ฌ๋ฌ ๊ฐ ์กด์ฌํด๋ "BOARD" ๊ถํ์ ๊ฐ์ง ID๋ฅผ ์ถ์ถ์ด ๊ฐ๋ฅํด์ ธ ์ ์์ ์ผ๋ก ๋ฆฌ์คํธ๊ฐ ์์ฑ๋์๋ค.
์ธ๋ฒ์งธ ํ ํ๋ก์ ํธ ์๋ฃ! ํ๋๋ฐ
๋ด๋ (2์ผ๋ค) ๋ง์ง๋ง ์ต์ข ํ๋ก์ ํธ๊ฐ ๋ค๊ฐ์จ๋ค.
๊ธฐ๋๋๋ฉด์ ๋จ๋ฆฐ๋ค ๐ฅน
[KPT ํ๊ณ ] Owner 5์กฐ์ ์ฌํ ํ๋ก์ ํธ