Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: 웹 페이지로 스타카토 공유하기 #575

Open
2 tasks
BurningFalls opened this issue Dec 26, 2024 · 8 comments
Open
2 tasks

feat: 웹 페이지로 스타카토 공유하기 #575

BurningFalls opened this issue Dec 26, 2024 · 8 comments
Assignees
Labels
backend We are backend>< confirm need confirmation! feat 기능 (새로운 기능)
Milestone

Comments

@BurningFalls
Copy link
Contributor

해당 기능은 아직 개발단계에 들어가지 않아도 되는 후순위 기능이지만, 생각해보다가 고민되는 부분들이 있어서 미리 작성해서 올려놓습니다!

🥸 어떤 기능인가요?

기능 Flow 1 - 공유 링크 생성 단계

  1. 사용자가 앱에서 특정 스타카토의 "공유하기" 버튼을 누른다.
  2. 모바일 클라이언트는 POST 요청을 백엔드 API(ex. /share)로 보낸다.
    요청에는 공유하려는 스타카토의 식별자(momentId)와 사용자 인증 토큰(Authorization)이 포함된다.
  3. 백엔드는 공유 링크를 생성한다. 여기에는 아래 과정이 포함된다.
    • 해당 사용자가 이 스타카토의 소유자인지 확인한다.
    • 고유하고 암호화된 토큰을 생성한다. (ex. UUID or JWT)
    • 토큰으로 공유 링크(URL)을 구성한다.
      (ex. https://staccato.kr/shared-moment?token=<encryptedToken>)
    • momentId, <encryptedToken>, 만료 시간을 데이터베이스에 저장한다.
  4. 백엔드는 모바일 클라이언트에 공유 링크를 보낸다.
  5. 모바일 클라이언트는 사용자가 링크를 알 수 있도록 화면에 표시한다.

기능 Flow 2 - 공유 링크로 웹페이지 접근 단계

  1. 사용자가 웹에서 공유된 링크를 클릭한다.
  2. 웹 클라이언트는 링크에 포함된 token을 추출한 뒤, 이를 백엔드로 보내어 스타카토 데이터를 요청한다.
    • GET /shared-moment?token=<encryptedToken>
  3. 백엔드는 스타카토를 조회한다. 여기에는 아래 과정이 포함된다.
    • 토큰이 유효한지, DB에 있는지를 확인한다.
    • 만료 시간이 초과되지 않았는지 확인한다.
    • 검증에 성공하면, 해당 momentId를 조회하여 스타카토 정보를 가져온다.
    • 검증에 실패하면, 적절한 에러 메시지를 반환한다.
  4. 백엔드는 스타카토 정보를 웹 클라이언트에 반환한다.
  5. 웹 클라이언트는 받은 정보를 기반으로 스타카토 내용을 화면에 표시한다.

고민해볼 부분 1 - 공유 토큰 종류 설정

  • UUID vs JWT에 대한 의견이 궁금합니다. 제가 생각하는 각각의 장점은 아래와 같습니다.
  • UUID로 토큰을 생성하는 경우
    • 생성 과정과 설계가 단순하다.
  • JWT로 토큰을 생성하는 경우
    • 만료 시간을 자체적으로 포함하고 있기 때문에, DB에 이를 저장할 필요가 없다.

고민해볼 부분 2 - 테이블의 PRIMARY KEY 설정

  • Primary Key를 momentId vs <encryptedToken> 둘 중 무엇으로 설정하는 것이 좋을지에 대한 의견이 궁금합니다. 제가 생각하는 각각의 장점은 아래와 같습니다.
  • momentId를 Primary Key로 설정하는 경우
    • 하나의 스타카토에 대해서 중복 링크가 생성되지 않는다. 따라서 링크가 만료되기 전에 새로운 링크를 생성하면, 값이 덮어씌워지면서 이전 링크가 자동으로 사라지는 효과를 얻을 수 있다.
  • <encryptedToken>를 Primary Key로 설정하는 경우
    • 기능 Flow 2에서 스타카토를 조회할 때 토큰으로 조회하는데, 이미 토큰을 기준으로 정렬되어 있어서 추가 인덱스를 설정할 필요가 없다.

✅ 작업 내용

논의 후 결정

😇 이때까지 끝낼게요!

논의 후 결정

🙇‍♀️ 이슈 확인했어요:)

팀원에게 이슈 확인을 부탁해요! 이슈를 확인한 팀원은 체크 표시를 해주세요!

@BurningFalls BurningFalls added backend We are backend>< feat 기능 (새로운 기능) confirm need confirmation! labels Dec 26, 2024
@BurningFalls BurningFalls added this to the sprint-7 milestone Dec 26, 2024
@BurningFalls BurningFalls self-assigned this Dec 26, 2024
Copy link
Contributor

  • 토큰 유형
    어떤 토큰을 사용해도 상관없을 것 같습니다. 다만, jwt로 만료 기한이 따로 있다고 해도 DB에 있는 데이터를 삭제하기 위한 로직이 따로 필요하지 않나요?
  • PK
    두 개의 키 중 하나를 PK로 사용하지 않고, 해당 테이블만의 PK를 따로 두어도 상관은 없을 것 같아요. 만약 둘 중 하나를 PK로 사용할 거라면, 다른 엔티티와 다른 키 생성 전략을 사용한다는 불편함이 있을 것 같습니다.
    특히, MomentId는 pk로서 적합하지 않은 것 같아요. (같은 데이터에 대해 서로 다른 공유 링크를 사용할테니까요?)

@BurningFalls
Copy link
Contributor Author

jwt로 만료 기한이 따로 있다고 해도 DB에 있는 데이터를 삭제하기 위한 로직이 따로 필요하지 않나요?

로직은 따로 필요하지만, 만료 기간이라는 애트리뷰트를 따로 저장하지 않아도 되니까 DB의 저장 공간에서 차이가 발생할 것 같아서 적어놓았습니다. 그런데 저희는 어차피 createdAt을 사용하고 있으니까 별로 신경쓸 부분이 아닌 것 같다고 생각은 하고 있습니다. 개발하려는 기능 관점에서 jwt가 uuid에 비해 가지는 특별한 장점이 없다면, uuid를 사용하는 것이 편할 것 같습니다.

해당 테이블만의 PK를 따로 두어도 상관은 없을 것 같아요. 만약 둘 중 하나를 PK로 사용할 거라면, 다른 엔티티와 다른 키 생성 전략을 사용한다는 불편함이 있을 것 같습니다.

생각해보니 테이블의 primary key는 항상 따로 두면서 만들고 있었네요. 새로 생성되는 테이블도 리니 말씀대로 다른 테이블과 똑같은 키 생성 전략을 사용하면 될 것 같습니다!

@BurningFalls
Copy link
Contributor Author

BurningFalls commented Dec 26, 2024

고민해볼 부분 3 - 동일한 스타카토에 대한 중복 링크 생성 가능 여부

테이블의 primary key가 momentId가 아니라면, 동일한 스타카토에 대해 공유 링크가 여러 개 생길 수도 있습니다.
동일한 스타카토의 중복 링크 생성을 제한할지 제한하지 않을지에 대한 의견도 궁금합니다.

Copy link
Contributor

동일 스타카토에 대한 중복 링크 생성을 막을 이유는 딱히 떠오르지 않았어요.
오히려 동일 스타카토에 대해 링크 공유 시도 시 덮어쓰기 된다면, 링크 유효 기간이 연장되는 것과 같은 효과가 발생하기 때문에 유효 기간을 설정하려던 의도를 벗어난 효과를 낼 수 있다고 생각했습니다. 물론, 너무 많은 링크 생성이라는 문제가 생길 수 있을 것 같아요. 지금은 사용자가 많지 않으니 우선 중복 링크 생성을 허용하고, 후에 최적화해보면 어떨까요?

@BurningFalls
Copy link
Contributor Author

동일한 스타카토의 중복 링크 생성을 제한하는 경우

  • 해당 스타카토의 공유 링크가 존재하는지 검사하는 로직이 필요하다. -> 링크 생성에 시간이 더 소요되는 단점이 있다.

동일한 스타카토의 중복 링크 생성을 제한하지 않는 경우

  • 링크 생성을 누를 때마다 무제한으로 새로운 링크가 생성된다. -> 물론 만료 시간이 존재하지만, 그럼에도 불구하고 데이터 양이 너무 많아진다는 단점이 있다.

@BurningFalls
Copy link
Contributor Author

오히려 동일 스타카토에 대해 링크 공유 시도 시 덮어쓰기 된다면, 링크 유효 기간이 연장되는 것과 같은 효과가 발생하기 때문에 유효 기간을 설정하려던 의도를 벗어난 효과를 낼 수 있다고 생각했습니다.

이 부분은 미처 생각하지 못했던 부분이네요. 확실히 원래 저희의 의도와 달라지는 것이라고 생각합니다.

물론, 너무 많은 링크 생성이라는 문제가 생길 수 있을 것 같아요. 지금은 사용자가 많지 않으니 우선 중복 링크 생성을 허용하고, 후에 최적화해보면 어떨까요?

점진적 개선을 적용해볼 수 있겠네요. 동의합니다!

@Ho-Tea
Copy link
Contributor

Ho-Tea commented Dec 31, 2024

확실히 링크 정보를 디비에 저장하게 되면서, 많은 고민거리가 생기게 된 것 같습니다.
링크를 공유해서 웹으로 보여주게하는 것이 주 목적이기 때문에 아래와 같은 방법도 생각해보았는데, 의견 부탁드려요!

아예 링크 공유와 관련된 정보를 디비에 저장하지 않는 방식으로 생각해보았습니다.

공유하기 버튼 클릭 시

  • 공유하기 버튼을 누르게 된다면 momentIdexpiration time(임의의 토큰 만료시간)을 payload로 설정하여 JWT 토큰을 발급한 후 링크를 반한한다.
    • payload에 같이 보여주고 싶은 정보들을 포함한다 (ex: 댓글, 기분)
  • 예시 : https://staccato.kr/shared-moment?token=<encryptedToken>

해당 링크를 다른 사람이 클릭하여 접근 시

  1. 토큰이 만료되었다면?
  • 새로운 렌더링 페이지를 반환한다. (ex 404.html)
  1. 토큰이 만료되지 않았다면?
  • momentId를 추출하여 해당 momentId를 조회한 후 페이지를 렌더링한다.
  • 추가 payload 값이 있다면 조합해서 페이지를 렌더링

보안측면에서의 이슈?

  • 링크를 생성하고 해당 링크를 공유하는 것이기에 어떠한 사용자든 해당 링크가 있다면 접근하여 열람할 수 있습니다.
  • 사실상 공유를 제한하고 싶은 사람에 대한 정보를 사전에 입력해놓지 않는다면 열람을 제한할 방법은 없어보입니다.
  • Notion 링크 공유와 유사하다고 생각하여 보안 측면에서 그렇게 크리티컬하지 않다고도 판단했습니다.

@linirini
Copy link
Contributor

linirini commented Jan 2, 2025

확실히 링크 정보를 디비에 저장하게 되면서, 많은 고민거리가 생기게 된 것 같습니다. 링크를 공유해서 웹으로 보여주게하는 것이 주 목적이기 때문에 아래와 같은 방법도 생각해보았는데, 의견 부탁드려요!

아예 링크 공유와 관련된 정보를 디비에 저장하지 않는 방식으로 생각해보았습니다.

공유하기 버튼 클릭 시

  • 공유하기 버튼을 누르게 된다면 momentIdexpiration time(임의의 토큰 만료시간)을 payload로 설정하여 JWT 토큰을 발급한 후 링크를 반한한다.

좋은 것 같아요! 토큰도 굳이 쿼리 스트링에 노출할 필요 없이 헤더에 담아놓을 수 있을 것 같네요!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
backend We are backend>< confirm need confirmation! feat 기능 (새로운 기능)
Projects
Status: No status
Development

No branches or pull requests

3 participants