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

[Team02] 깃허브 로그인 구현, 라벨 수정/이슈 필터링 카운트 기능 수정 #91

Open
wants to merge 22 commits into
base: team-02
Choose a base branch
from

Conversation

zzawang
Copy link
Member

@zzawang zzawang commented May 30, 2024

4주동안 감사했습니다 우디 😊 👍🏻

배포된 저희의 사이트입니다 ☺️ 👉🏻 이슈트래커


✅ 구현 내용

  • 깃허브 로그인
  • 라벨 수정/이슈 필터링 카운트 기능 수정
  • nginx로 http ➡️ https 포워딩 적용
  • 프론트, 서버 모두 배포하여 도메인 적용 (https)

(저번주 PR에 JWT, Redis를 적용했는데 PR 메시지에는 적지 못하여 혹시 못보셨을까봐 다시 적어봅니다..!)

  • JWT 구현
  • Redis 적용



🤔 고민과 🙋🏻 질문

  • 이번에 배포를 하면서 인프라때문에 고생을 했는데 🥲, 실무에서는 백엔드 개발자가 인프라 관련 지식을 얼마나 알고있어야 하는지 궁금합니다!
  • Oauth Github login을 구현하면서 궁금했던 점인데, Oauth 자원 서버의 API로는 비밀번호를 제공하지 않는것으로 알고있는데 이런 경우 실무에서는 비밀번호 처리를 어떻게 하는지 궁금합니다. 저희는 멤버 DB에 저장하기 위해 Github login을 한 사용자는 비밀번호를 UUID로 생성하여 저장했습니다. 이 밖에도 Oauth로 로그인하는 사용자를 일반 회원가입 한 사용자와 구분하여 DB로 관리하는지 처리 과정이 궁금합니다.



zzawang and others added 22 commits May 29, 2024 20:25
- Access token을 요청하여 사용자 정보를 가져온다.
- 이미지 URL을 byte 배열로 변환한 후 변환된 배열로 MultipartFile 객체를 생성한다.
- 회원가입을 하기위해 필요한 MemberCreateDto로 매핑한다.
- 처음 사용자가 깃허브 로그인을 하는 것이라면 회원가입 로직을 수행한다.
- 사용자에게 유저 정보와 JWT 토큰을 전달한다.
- 프로필 이미지를 MultipartFile로 변환하여 메타데이터와 함께 저장한다.
- 라벨 개수와 마일스톤 개수를 구하여 반환한다.
- 필터링된 이슈의 개수를 구하는 것이 아니라 전체 이슈의 개수를 구하고 있어 수정하였다.
- Entity의 @Setter를 삭제하면서 구조가 변경됨에 따라 라벨이 수정되는 것이 아니라 생성되는 오류가 발생하여 수정용 Mapper를 추가하였다.
@zzawang zzawang requested a review from jihye-woo May 30, 2024 07:18
@zzawang zzawang added the review-be Extra attention is needed label May 30, 2024
@zzawang zzawang changed the title 깃허브 로그인 구현, 라벨 수정/이슈 필터링 카운트 기능 수정 [Team02] 깃허브 로그인 구현, 라벨 수정/이슈 필터링 카운트 기능 수정 May 30, 2024
@jihye-woo
Copy link

이번에 배포를 하면서 인프라때문에 고생을 했는데 🥲, 실무에서는 백엔드 개발자가 인프라 관련 지식을 얼마나 알고있어야 하는지 궁금합니다!

  • 회사 상황마다 다릅니다. 회사에서 devops, 인프라를 담당하는 사람이 충분하고, 인프라를 사용하는 내부 개발자 툴이 제대로 갖춰져있을 경우에는 인프라 지식이 아예 필요하지 않은 경우도 있습니다. 인프라를 담당하는 분들의 목표는 '다른 개발자들이 인프라 지식을 몰라도 인프라 리소스를 사용할 수 있도록'하는 것이기 때문입니다.
  • 반면 규모가 작아 개인이 맡는 범위가 크거나 팀에게 부여된 책임과 자율성이 높은 회사일 경우 인프라 지식을 어느정도 요구하는 경향이 있습니다.
  • 다만 지금은 백엔드 개발을 위해 필요한 수준으로만 인프라 지식을 습득해도 충분할 것 같습니다. 처음부터 SRE, devops 직군으로 가지 않는 이상 인프라를 모른다고 엄청 큰 흠이 되거나 하진 않다고 생각합니다. 알면 플러스, 몰라도 그 포지션에서 가장 주요하게 해야하는 일을 잘 할 수 있다면 크게 문제가 되지 않을 것 같습니다.

Oauth Github login을 구현하면서 궁금했던 점인데, Oauth 자원 서버의 API로는 비밀번호를 제공하지 않는것으로 알고있는데 이런 경우 실무에서는 비밀번호 처리를 어떻게 하는지 궁금합니다. 저희는 멤버 DB에 저장하기 위해 Github login을 한 사용자는 비밀번호를 UUID로 생성하여 저장했습니다.

  • 회사마다 해당 상황에 대해 핸들링하는 방법은 다양할 것 같습니다. 정답이 있는 부분은 아니고 말씀해주신 방식으로 해결하는 방식도 좋다고 생각합니다.

이 밖에도 Oauth로 로그인하는 사용자를 일반 회원가입 한 사용자와 구분하여 DB로 관리하는지 처리 과정이 궁금합니다.

  • 이 부분도 정답이 있는 것은 아닙니다. 회사마다 다를 수 있기 때문에 정답을 ,

주신 질문들이 전반적으로 정답을 찾고 계신 느낌이었는데, 정해진 답이 있는 영역이 아니기 때문에 모호한 답변을 드리게된 점 양해 부탁드립니다. 매 PR때마다 말씀드리는 점이지만, 실무에서 하는 방식이 항상 정답이 아니기도 하고 처해진 상황마다 정답이 다를 수 있다고 생각합니다. 그리고 구체적인 방법론이나 코드/데이터 구조를 궁금해하시는 것 같았습니다. 자세하게 말씀드리는 것도 회사 내부의 코드나 데이터 구조를 알려드리는 느낌이라 너무 디테일하게 말씀드리기는 조심스러운 점 또한 양해 부탁드립니다

Copy link

@jihye-woo jihye-woo left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

마지막까지 고생 많으셨습니다!!

그동안 리뷰 반영이며, 디테일한 질문들을 보면서 프로젝트에 정말 몰입도 있게 임해주고 계신다고 생각이 들어 저도 덕분에 열심히 알아보시면 좋을 요소들 혹은 생각해보면 좋을만한 질문들을 드리려고 노력할 수 있었습니다

다음에 기회가 되면 또 뵙길 바라요⭐️ 다시 한 번 한 달동안 고생하셨습니다🙏

* byte 배열을 MultipartFile 객체로 변환하기 위한 클래스
*/
public class CustomMultipartFile implements MultipartFile {
private final Tika tika = new Tika();

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

제가 Tika를 잘 모르긴하지만, 유틸성 느낌이 강하다고 한다면 static하게 설정해주는 것도 좋을 것 같습니다!

인스턴스 별로 (1) 다르게 가지고 있어야하는 필드와 (2) 모든 인스턴스들이 공유해도 괜찮은 필드를 구분해서 생각해주시면 좋습니다😃

@Getter
@ToString
@Builder
@EqualsAndHashCode

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

동일성 vs 동등성 개념의 차이를 확인해보시면 좋을 것 같습니다!

Comment on lines +52 to +53
long openedCount = filteredIssues.stream().filter(issue -> issue.getIsClosed().equals(false)).toList().size();
long closedCount = filteredIssues.stream().filter(issue -> issue.getIsClosed().equals(true)).toList().size();

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

로직이 너무 길어지고, 가독성을 챙기고 싶다면
데이터와 그 데이터와 관련된 로직이 응집될 수 있도록, 객체 내부로 로직을 안으로 숨기는 것도 방법일 것 같습니다!

issue.getIsClosed().equals(false)
-> issue.isNotClosed()

issue.getIsClosed().equals(true)
-> issue.isClosed()

@@ -16,7 +16,6 @@ public class Label {
private final Long id;
private final String name;
private final String description;
@Column("text_color")
private final String textColor;
@Column("background_color")
private final String bgColor;

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

개인차가 있겠지만, 저는 길더라도 이름을 보고서 어떤 것을 의미하는지가 명확하게 드러나는 것을 선호하는 편입니다!
추후 1년뒤, 2년뒤 처음 코드를 접하는 사람이 볼 때도 최대한 알아볼 수 있도록 네이밍을 하는 것의 장점도 생각해주시면 좋을 것 같아요😃

@@ -53,7 +55,7 @@ public Label createLabel(LabelDto labelDto) {
public Label modifyLabel(LabelDto labelDto, Long id) {
validateBgColor(labelDto);

Label label = toLabel(labelDto);
Label label = LabelMapper.toModifiedLabel(id, labelDto);

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

👍

Comment on lines +24 to +27
private final GithubLoginService githubLoginService;
private final MemberService memberService;
private final LoginService loginService;
private final FileService fileService;

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

GithubLoginService과 LoginService 서비스명에서 기대하는 클래스의 역할과 실제 역할이 다른 느낌을 받았습니다. 네이밍을 좀 더 명확하게 해주시면 좋을 것 같아요 (처음 이름만 보고서는 일반 로그인 서비스와 깃헙 로그인 서비스를 구분하기 위해서라고 생각했어요!)
그리고 두 서비스 로직들이 컨트롤러에 있어야할지, 서비스에 있어야할지도 함께 고민해볼만한 요소라 생각합니다

추가로 (1) OAuth를 여러 개 사용했을 때 혹은 (2) OAuth 구현을 깃헙이 아닌 다른 것으로 교체되었을 때의 상황도 고려해보시면 좋습니다!

@Builder
@ToString
@Getter
public class AccessTokenRequest {

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Request만 스네이크 케이스군요!
JsonProperty 혹은 JsonNaming으로 어플리케이션 내부에서 사용하는 네이밍 전략의 일관성을 맞춰주는 방법도 있습니다👍

Comment on lines +31 to +38
OAuthInfo oAuthInfo = webClient.post()
.uri("https://github.com/login/oauth/access_token")
.contentType(MediaType.APPLICATION_JSON)
.bodyValue(getAccessTokenRequest(code))
.accept(MediaType.APPLICATION_JSON)
.retrieve()
.bodyToMono(OAuthInfo.class)
.block(); // 비동기 결과를 동기적으로 대기

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

webClient가 기본적으로 비동기 방식으로 동작해서 동기 코드로 변경해주신거군요

crongro pushed a commit that referenced this pull request Jun 3, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
review-be Extra attention is needed
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants