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

인증 기능 구현 #46

Merged
merged 20 commits into from
Jan 25, 2023
Merged

인증 기능 구현 #46

merged 20 commits into from
Jan 25, 2023

Conversation

Wo-ogie
Copy link
Member

@Wo-ogie Wo-ogie commented Jan 22, 2023

작업 사항

  • Spring Security 도입 및 설정
    • JWT_SECRET_KEY는 보안 상 민감한 정보이므로 환경변수 설정으로 주입받아서 사용해야 함.
  • 인증 기능에 필요한 코드 구현
    • UserDetailsService, UserDetails의 구현체 작성
  • Member domain spec 수정
    • 회원가입 로직 상 카카오 로그인/회원가입이 우선 처리된 후에 폰번호와 주소를 입력받아야 함. 이에 따라 addressphoneNumber를 nullable로 설정.
      • 인증받은 번호와 주소를 입력받아 저장하는 기능도 곧이어 구현해야 함.
    • 카카오 비즈니스 권한 상 출생년도를 받을 수 없어 연령대로 수정하였음.
    • Spring Security 기능에 필요하여 역할(RoleType) 속성을 추가하였음.
    • 이에 따라 MemberDto도 적절히 수정하였음.
  • MemberDto 내부의 주소를 Address가 아닌 AddressDto로 변경.
    • 현재 open session in view 설정을 껐기 때문에, controller layer에서 lazy loading이 되지 않는다. 지금 당장은 문제가 되지 않지만 버그가 발생할 여지가 있기 때문에, Dto 내부의 필드에는 entity를 넣지 않는 것이 바람직해 보인다.
  • 로그인 기능 구현
    • JWT 검증 filter 적용
    • Kakao에 access token을 전달하여 회원 정보 요청
    • 회원 존재 여부 판단 후 회원가입/로그인 로직 처리
    • JWT 발급
    • 로그인 권한이 필요한 대부분의 API들은 header에 access token을 갖고 있어야 접근 가능함. (Authorization = Bearer 액세스토큰)
    • API에서 로그인 사용자의 정보가 필요한 경우 @Parameter(hidden = true) @AuthenticationPrincipal WithMeAppPrinciple principle를 api method의 parameter로 추가하면 된다.
      • 그 후 principle.getUsername()으로 로그인 사용자의 이메일을 받아올 수 있다.
      • @Parameter(hidden = true)는 Swagger 명세에 표시하고 싶지 않은 parameter를 감추기 위한 annotation임.
    • 현재 access token의 만료 기한을 7일로 여유롭게 잡아두고 refersh token, 로그아웃 기능은 구현하지 않았음. 추후 구현할 예정이나, 현재 사용하는 데에는 문제 없고 데모데이까지 시간이 많지 않아 일단 후순위로 미뤄둘 예정.
  • 인증 기능 구현에 따른 Swagger 테스트 환경 설정 추가
    • 이제 대부분의 기능들은 로그인이 필요하기 때문에 Swagger에서도 access token을 header에 설정하여 테스트 해볼 수 있도록 Swagger 설정을 추가하였음.
    • 앞으로 로그인 사용자가 사용할 API들은 Swagger 명세를 작성할 때 반드시 @Operation(security = @SecurityRequirement(name = "access-token"))를 붙여주어야 함.
  • JPA Auditing 기능으로 생성자, 수정자 기입할 수 있도록 구현
    • 현재 생성자, 수정자를 입력을 테스트 해볼만한 기능이 없는 관계로, 추후에 테스트 할 예정.

참고 자료

체크리스트

  • PR의 제목은 팀 내 규칙을 준수하여 알맞게 작성하였는가?
  • Merge 하는 브랜치가 올바른가? (main branch에 실수로 PR 생성 금지)
  • 팀의 코딩 컨벤션을 준수하는가?
  • PR과 관련없는 변경사항이 들어가지는 않았는가?
  • 내 코드에 대한 자기 검토가 되었는가?
  • Reviewers, Assignees, Lables, Project, Milestone은 적절하게 선택하였는가?
  • 관련한 issue를 닫아야 하는지 점검해보고 적용했는가?

인증 기능(로그인) 구현에 필요한 Spring Security와 JWT 의존성을 추가했다.
개행을 넣어서 로그를 출력하니 오히려 보기 어려워졌다. 때문에 error 정보임을 더 명확히 알 수 있도록 로그 출력 내용을 수정하였음.
다만, jwt secret key는 민감 보안 정보이므로 외부에 공개하면 안된다. 때문에 환경 변수를 통해 외부에서 주입받도록 하여 보안 정보를 감추었다.
Jwt secret key 값은 팀 내 문서를 참고할 것
Spring Security 추가 후 서비스에 필요한 설정들을 추가해주었다. 
현재 코드에 아직 구현되지 않은 JWT 관련 코드들이 있지만, 일단 그냥 commit 하도록 한다. 
다음부터는 주의해서 commit 해야 할 필요 있음.
Service layer의 method는 controller layer 이외에도 다른 곳에서 사용할 가능성이 있다. 이를 고려하여 설명을 자연스럽게 수정하였음.
또한 `MemberDto`에 대한 link를 추가하여 method 명세에서 해당 class를 바로 확인할 수 있도록 하였음.
1. `Member` domain 수정
  - 회원가입 로직 상 카카오 로그인/회원가입이 우선 처리된 후에 폰번호와 주소를 입력받아야 함. 이에 따라 address와 phoneNumber를 nullable로 설정
  - 카카오 비즈니스 권한 상 출생년도를 받을 수 없어 연령대로 수정하였음.
  - Spring Security 기능에 필요하여 역할 속성을 추가하였음.
  - 이에 따라 MemberDto도 적절히 수정하였음.

2. `MemberDto` 내부의 주소를 `Address`가 아닌 `AddressDto`로 변경.
  - 현재 open session in view 설정을 껐기 때문에, controller layer에서 lazy loading이 되지 않는다. 지금 당장은 문제가 되지 않지만 버그가 발생할 여지가 있기 때문에, Dto 내부의 필드에는 entity를 넣지 않는 것이 바람직해 보인다.

3. `UserDetailsService`, `UserDetails`의 구현체 작성
  - 인증 기능 구현에 필요한 Spring Security interface의 구현체를 작성하였다. Username은 이메일로, password는 각 OAuth 플랫폼의 고유 번호로 사용하려고 한다.

4. JWT 기반 로그인, 회원가입 business logic 구현

5. JWT 인증 filter 적용
  - 인증 기능이 필요한 api에 JWT 검증 로직을 추가한다.
ccbc43c 에서 기존에 nickname을 기반으로 회원을 조회하던 method와 새로이 email을 기반으로 회원을 조회하는 method의 이름 통일성을 고려하여 변경하였다.
일반적으로 get은 이미 존재한다는 가정하에 조회할 때 많이 사용하는 표현이므로 find로 사용하였음.
- Kakao API server에 access token을 전송하여 회원 정보를 받아온 후, 서비스 내에서 로그인/회원가입 로직을 처리하는 web layer 기능 구현.

- 이제 대부분의 기능들은 로그인이 필요하기 때문에 Swagger에서도 access token을 header에 설정하여 테스트 해볼 수 있도록 Swagger 설정을 추가하였음.
생성자, 수정자는 로그인을 한, 요청을 보낸 회원의 PK(id)를 기입하여 등록되도록 한다.
이 test는 Spring Data JPA가 만들어주는 기능에 대한 test이므로 굳이 필요하지 않다. 때문에 disabled 처리하였음.
@Wo-ogie Wo-ogie added 💫 feature 기능 구현 ✅ test 테스트 ⚙️ chore 설정 및 의존성 관련 labels Jan 22, 2023
@Wo-ogie Wo-ogie self-assigned this Jan 22, 2023
@Wo-ogie Wo-ogie linked an issue Jan 22, 2023 that may be closed by this pull request
13 tasks
@Wo-ogie Wo-ogie marked this pull request as ready for review January 22, 2023 13:03
@Wo-ogie Wo-ogie changed the title (작성 중) 인증 기능 구현 인증 기능 구현 Jan 22, 2023
@Wo-ogie
Copy link
Member Author

Wo-ogie commented Jan 22, 2023

현재 JpaConfig에서 jpa auditing 기능을 수행할 때 principle의 값이 String으로 넘어와 cast exception이 발생하는 버그를 발견, fix 후 PR을 다시 열도록 할 예정임.

@Wo-ogie Wo-ogie closed this Jan 22, 2023
로그인하지 않은 상황에서 `Authentication.getPrincipal()`을 사용하면 "anonymousUser"라는 String이 반환된다.
이 경우, `WithMeAppPrinciple`로 casting 할 수 없어 `ClassCastException`이 발생한다.
이 때문에 `Optional.empty()`를 반환하도록 구현.
@Wo-ogie
Copy link
Member Author

Wo-ogie commented Jan 23, 2023

107ed50 로 버그 수정하였음

@Wo-ogie Wo-ogie reopened this Jan 23, 2023
이 경우 발생한 exception이 외부로 던져지지 않고 catch와 `return Optional.empty()`로 인해 처리되고 있다.
따라서 error보다는 warn으로 logging level을 변경하여 주의사항으로만 인지할 수 있도록 하는 것이 좋다고 판단하였음.
Access token이 만료되는 등의 이유로 kakao와의 통신에 실패한 경우, 사용자에게 카카오 서버 통신 문제라는 것을 응답하기 위해 try-catch로 예외처리하는 로직을 추가하였음.
@Wo-ogie Wo-ogie merged commit 5f0cf8a into develop Jan 25, 2023
@Wo-ogie Wo-ogie deleted the feature/#29-kakao-login branch January 25, 2023 05:02
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
⚙️ chore 설정 및 의존성 관련 💫 feature 기능 구현 ✅ test 테스트
Projects
Status: Done
Development

Successfully merging this pull request may close these issues.

인증 기능 구현
4 participants