Project/토이 프로젝트 30

[Refactoring] 여러 소셜 로그인을 위한 공통영역 분리

OAuth2.0 소셜 로그인 회원 정보 받는 곳을 한 패키지에서 관리합니다. 전 Google과 Naver만 구현했지만 트위터, 카카오 등 원하는 만큼 클래스를 생성해서 구현할 수 있습니다. OAuth2UserInfo public interface OAuth2UserInfo { String getProviderId(); String getProvider(); String getEmail(); String getName(); } 공통적으로 가져올 정보입니다. GoogleUserInfo public class GoogleUserInfo implements OAuth2UserInfo{ private Map attributes; // oauth2User.getAttributes() public GoogleUser..

[Git] Git 특정 커밋 삭제 (git rebase -i)

토이프로젝트를 하면서 OAuth2.0으로 구글 소셜 로그인 기능 구현 후 github에 코드를 올렸습니다.(A) 분명 .gitignore에 해당 설정 파일을 추가했는데 git캐시 문제로 Credential 한 정보들이 노출되었습니다. 그 후로 캐시 내용을 전부 삭제 후 다시 커밋해서 내리긴 했지만(B) Credential한 정보가 담겨있는 커밋 내용(A)을 누르면 나오더군요... 아찔 합니다. github 보안팀에서도 제 메일로 "너 개인정보 노출됨! 알고 있는 거 맞아?"라는 메일이 왔습니다. 과거 git을 다뤘을 때 데이터를 날려먹거나 충돌난 적이 몇 번 있었어서 다시 만지기 두려웠지만, 해야죠 ㅎㅎ 이런 일은 끔찍하지만 계속 해보면서 점점 자신감이 붙길 바랍니다. 커밋 히스토리를 수정해야하는 경우 ..

[Cinemagram] 소셜 로그인 (구글) - (13)

일반 로그인뿐만 아니라 OAuth2 로그인을 추가로 구현 후 통합 할 예정입니다. 관련 포스팅의 순서는 다음과 같습니다. 소셜 로그인 (구글) - (13) [Refactoring] 여러 소셜 로그인을 위한 공통영역 분리 소셜 로그인 (구글, 네이버) - (14) 이번 포스팅에서는 구글 소셜 로그인 구현에 집중해 보겠습니다. 시프링 시큐리티 설정 build.gradle > dependencies 스프링 시큐리티 관련 의존성 추가 // Oauth2 implementation 'org.springframework.boot:spring-boot-starter-oauth2-client' spring-boot-starter-oauth2-client 소셜 로그인 등 클라이언트 입장에서 소셜 기능 구현시 필요한 의존성..

[Git] .gitignore가 작동하지 않을때

OAuth2.0 로그인을 개발할 때 application-oauth.yml에는 id와 secret이 들어갑니다. 이 정보는 공유되면 안 되므로 .gitignore에 추가해야 합니다. 하지만 추가했음에도 git에 올라간다면 git의 캐시 문제이므로 아래 명령어을 차례대로 실행해 캐시 내용을 전부 삭제 후 다시 커밋하면 됩니다. git rm -r --cached . git add . git commit -m "fixed untracked files" 해당 이슈를 발견한 포스팅은 [Cinemagram] 소셜 로그인 (구글) - (13)입니다.

[Cinemagram] hover 효과 및 프로필 사진 등록 - (12)

10. 좋아요 기능 구현 11. Popular 페이지 렌더링 포스팅에 이어 추가적으로 마우스 hover 시 좋아요 카운드를 보여주고 프로필 사진 등록 구현까지 해서 Popular페이지와 Profile페이지를 마무리 짓도록 하겠습니다. 마우스 hover 시 좋아요 카운드 보여주기 좋아요 기능 구현에서 만든 likesCount를 여기서 활용할 수 있습니다. 기능 구현할 수 있는 두 가지 방법 소개 이렇게 찍어내는 방법에는 두 가지가 있습니다. html에 바로 로직을 넣는 방법 서버에서 로직을 짜고 html에는 결과만 넘기는 방법 Case 1. html에 바로 로직 넣기 Case 2. 서버에서 로직을 짜고 html에는 결과만 넘기는 방법 흐름 파악 UserController @GetMapping("/user/..

[Cinemagram] Popular 페이지 렌더링 - (11)

저번 포스팅까지 해서 좋아요 기능 구현이 끝이 났습니다. 이제 드디어 Popular페이지를 구현하도록 하겠습니다. 복습해 보자면, Popular페이지는 좋아요가 있는 사진들을 출력하는 페이지로 좋아요가 많은 순으로 나오게 됩니다. 이번 포스팅에서는 쿼리를 짜는 부분이 중점적으로 나옵니다. 최종 쿼리가 아닌 단계별 쿼리를 소개할 예정입니다. 이 정도는 앞으로도 짤 수 있게 계속해서 연습이 필요합니다. 익숙해져야 할 개념 서브 쿼리 인라인 뷰 : FROM절에 사용하는 서브 쿼리 스칼라 서브쿼리 : SELECT절에 사용하는 서브 쿼리 그룹 바이 조인 좋아요가 있는 이미지 출력 쿼리 관련 클래스 ImageController ImageService ImageRepository 로직과 nativeQuery 넣을 위..

[Cinemagram] 좋아요 기능 구현 - (10)

좋아요 기능 구현, Popular 페이지 렌더링을 연달아 구현할 예정입니다. Popular 페이지란? 좋아요가 많은 순서대로 Image를 출력하는 페이지입니다. 따라서 그전에 좋아요 기능을 먼저 구현해 보도록 하겠습니다. 좋아요 기능 구현 모델 만들기 & 연관관계 매핑 엔티티명은 MYSQL에 LIKE 함수가 존재하므로 Likes로 만들었습니다. 😁 @Transient 엔티티 필드로는 필요한데, DB 칼럼으로 만들고 싶지 않을 때 사용하는 어노테이션 어떤 필드들이 필요할까? 우리가 SNS에서 어떤 로직으로 좋아요를 누르는지 생각해보면 됩니다. 즉, 어떤 이미지를 누가 좋아했는지 알아야 합니다. 또한 특정 유저는 한 이미지를 딱 한 번만 좋아요 누를 수 있습니다. (다중 칼럼 UNIQUE 제약 조건) - 좋..

[Trouble Shooting] 무한 순환참조 이슈

토이 프로젝트를 하면서 순환참조 문제가 종종 발생하였습니다. 처음에는 당황했지만 차근차근 코드를 따라가 보니 해결할 수 있었습니다. 이번 포스팅에서는 크게 두 Case로 나눠서 어떻게 오류를 해결했는지 과정을 작성해 보겠습니다. Case 1. Jackson 라이브러리를 사용하여 엔티티를 JSON으로 변환 시, 무한참조 이슈 관련 모델 User Image Image import com.fasterxml.jackson.annotation.JsonIgnoreProperties; @NoArgsConstructor @Getter @Entity public class Image extends BaseTimeEntity { ... @JoinColumn(name = "userId") @ManyToOne(fetch = ..

[Cinemagram] 팔로우 기능 구현 - (9)

원래 이 기능은 가장 나중에 하려고 했습니다. 랜더링 하는 부분들을 구현한 후에 조금 복잡한 기능을 구현하는 게 정신건강에 좋을 것 같다는 판단이었습니다. 하지만 여러 테스트를 하던 와중 이와 같은 에러가 발생했습니다. Postman으로 구독 API 테스트 中 ERROR UsernamePasswordAuthenticationFilter : An internal error occurred while trying to authenticate the user. org.springframework.security.authentication.InternalAuthenticationServiceException: UserDetailsService returned null, which is an interface c..

[Trouble Shooting] JPA DTO Mapping - QLRM 라이브러리 사용

QLRM 라이브러리란 DB에서 Result 된 결과를 자바 클래스에 매핑해주는 역할을 합니다. Repository에 nativeQuery를 직접 짜서 날리면 되는 거 아닌가? Repository에 nativeQuery를 직접 짜서 넣으면 되는데 왜 굳이 QLRM 라이브러리를 추가해서 작업하는 것일까요? 그 이유는 특정 Repository는 특정 타입(Follow 모델)만 리턴하기 때문입니다. (상속받은 클래스 타입의 모델만 리턴) 따라서 직접 짠 쿼리의 결과가 특정 타입(Follow 모델)이 아니라면 Repository에 nativeQuery를 넣을 수가 없습니다. 실습할 코드는 DTO를 리턴해야 함 이처럼 DTO로 받아 내야 하는 쿼리의 경우 JpaRepository를 상속받은 인터페이스로 native..