-
Notifications
You must be signed in to change notification settings - Fork 0
[Jinyong] Week9 미션 #110
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
Open
LATE-BL00MER
wants to merge
22
commits into
Jinyong
Choose a base branch
from
Jinyong-week9
base: Jinyong
Could not load branches
Branch not found: {{ refName }}
Loading
Could not load tags
Nothing to show
Loading
Are you sure you want to change the base?
Some commits from the old base branch may be removed from the timeline,
and old review comments may become outdated.
Open
[Jinyong] Week9 미션 #110
Changes from all commits
Commits
Show all changes
22 commits
Select commit
Hold shift + click to select a range
ac02ae1
setting: JWT 및 Spring Security 의존성 추가
LATE-BL00MER 6365805
fix: AuthMember 사용자명 반환 로직 수정
LATE-BL00MER 46c2f7e
setting: OAuth2 Client 의존성 추가
LATE-BL00MER 6442e0c
feat: 카카오 OAuth 로그인 서비스 구현
LATE-BL00MER 7684c28
feat: 소셜 로그인 회원 조회 로직 추가
LATE-BL00MER 6079171
feat: JWT 인증 필터 로직 추가
LATE-BL00MER 4e5e728
feat: JWT 토큰 생성 및 검증 로직 추가
LATE-BL00MER 224a2e2
feat: 카카오 OAuth 응답 DTO 추가
LATE-BL00MER 225aa1f
feat: Member 엔티티에 소셜 로그인 필드 추가
LATE-BL00MER 4bfc059
feat: Member 컨트롤러에 로그인 및 내 정보 조회 API 추가
LATE-BL00MER ec8ac31
feat: MemberConverter에 소셜 로그인 변환 로직 추가
LATE-BL00MER 414655b
feat: 회원 인증 관련 에러 코드 추가
LATE-BL00MER 1699bd3
feat: 소셜 로그인 회원 조회 메서드 추가
LATE-BL00MER 6c7e3e4
feat: 로그인 요청 DTO 추가
LATE-BL00MER 55cd692
feat: 로그인 응답 DTO 추가
LATE-BL00MER bfe4d2f
feat: 일반 로그인 서비스 로직 추가
LATE-BL00MER bdb8f08
feat: OAuthDTO 인터페이스 추가
LATE-BL00MER e0aeae1
feat: OAuthMember 인증 객체 구현
LATE-BL00MER 087564b
feat: OAuth 로그인 성공 핸들러 구현
LATE-BL00MER 35f1247
feat: SecurityConfig에 JWT 및 OAuth 인증 설정 추가
LATE-BL00MER ca25ccb
feat: 소셜 로그인 타입 enum 추가
LATE-BL00MER 76cc906
docs: 9주차 핵심 키워드 정리 추가
LATE-BL00MER File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,95 @@ | ||
| - 세션과 토큰의 차이는? | ||
|
|
||
| **세션 기반 인증**: 서버가 사용자의 로그인 상태를 기억하는 방식 | ||
|
|
||
| → 사용자가 로그인 하면 서버는 세션 생성 | ||
|
|
||
| 브라우저에 JSESSIONID 같은 세션 ID가 담긴 쿠키 전달 | ||
|
|
||
| 이후 사용자가 요청을 보낼 때마다 쿠키가 함께 전송되고, 서버는 그 세션 ID를 보고 “이 사용자는 로그인한 사용자!”라고 판단함 | ||
|
|
||
| **토큰 기반 인증**: 서버가 로그인 상태를 직접 저장하지 않음. 클라이언트가 토큰을 들고 다니는 방식임 | ||
|
|
||
| → 로그인에 성공하면 서버가 JWT 같은 토큰 발급 | ||
|
|
||
| 클라이언트는 이후 요청마다 `Authorization: Bearer 토큰값` 형태로 토큰을 보냄 | ||
|
|
||
| → 서버는 토큰의 서명과 만료 시간 검증해 사용자 인증 | ||
|
|
||
| | 구분 | 세션 방식 | 토큰 방식 | | ||
| | --- | --- | --- | | ||
| | 저장 위치 | 서버가 세션 저장 | 클라이언트가 토큰 저장 | | ||
| | 서버 상태 | Stateful | Stateless | | ||
| | 요청 방식 | 쿠키 기반 | Authorization Header 기반 | | ||
| | 장점 | 서버에서 세션 삭제 가능, 제어 쉬움 | 서버 확장에 유리 | | ||
| | 단점 | 서버가 세션을 관리해야 함 | 토큰 탈취 시 만료 전까지 위험 | | ||
| | 예시 | 전통적인 웹 로그인 | JWT 기반 REST API 로그인 | | ||
|
|
||
| 최근에는 토큰 방식으로 로그인을 받는 추세이지만, 보안이 중요한 금융쪽이나 몇몇 분야는 세션방식을 고집한다. | ||
|
|
||
| - 엑세스 토큰과 리프레시 토큰이란? | ||
|
|
||
| **Access Token(액세스 토큰)**은 사용자가 보호된 API에 접근할 때 사용하는 실제 인증 토큰이다. | ||
|
|
||
| Ex) 마이페이지 조회, 리뷰 작성, 미션 등록 같은 private API 호출할 때 클라이언트는 Access Token을 `Authorization` 헤더에 담아 보낸다. | ||
|
|
||
| <aside> | ||
|
|
||
| Authorization: Bearer accessToken값 | ||
|
|
||
| </aside> | ||
|
|
||
| 서버는 토큰을 검증 후 정상이면 사용자를 인증 사용자로 처리한다. | ||
|
|
||
|
|
||
|
|
||
| **Refresh Token(리프레시 토큰)은 Access Token이 만료되었을 때 새로운 Access Token을 발급받기 위한 토큰이**다. | ||
|
|
||
| → API 요청에 직접 사용하는 토큰이 아니라 재발급용 토큰 | ||
|
|
||
| Access Token은 보통 탈취 위험을 줄이기 위해 짧게 유지한다(30분~2시간) | ||
|
|
||
| 하지만 Access Token이 너무 자주 만료되면 사용자는 계속 다시 로그인해야 | ||
|
|
||
| 하므로 불편함! | ||
|
|
||
| → 이 문제를 해결하기 위해 Refresh Token을 사용하는 것이다. | ||
|
|
||
| | 구분 | Access Token | Refresh Token | | ||
| | --- | --- | --- | | ||
| | 목적 | API 접근 | Access Token 재발급 | | ||
| | 사용 위치 | 매 요청마다 사용 | 토큰 재발급 시 사용 | | ||
| | 만료 시간 | 짧게 설정 | 상대적으로 길게 설정 | | ||
| | 노출 위험 | 자주 전송되기에 탈취 위험 있음 | 더 오래 유효하기 때문에 안전하게 보관 필요 | | ||
| | 예시 | 마이페이지 요청, 리뷰 작성 | Access Token 재발급 요청 | | ||
|
|
||
| Access Token은 “출입증”에 가깝고, Refresh Token은 “출입증을 다시 발급받을 수 있는 재발급 권한”에 가깝다. | ||
|
|
||
| - OAuth 1.0과 OAuth 2.0의 차이는? | ||
|
|
||
| OAuth는 사용자의 비밀번호를 직접 공유하지 않고, 제3자 애플리케이션이 사용자의 리소스에 제한적으로 접근할 수 있게 해주는 권한 위임 프로토콜이다. | ||
|
|
||
| 쉽게 말하면, “카카오로 로그인”, “구글로 로그인” 같은 기능이 OAuth 기반으로 동작하는 것이다. | ||
|
|
||
| 우리 서비스가 사용자의 카카오 비밀번호를 직접 받는 것이 아니라, 카카오가 인증을 처리하고 우리 서버는 카카오로부터 사용자 정보를 받아 회원가입 또는 로그인을 처리한다. | ||
|
|
||
| OAuth 1.0은 초기 OAuth 프로토콜이며, 요청마다 복잡한 서명 과정을 거쳐야 하고 클라이언트가 요청을 만들 때 암호화 서명값을 포함해야 한다. | ||
|
|
||
| OAuth 2.0은 위의 OAuth 1.0을 대체한 방식이다. OAuth 2.0 명세는 OAuth 1.0을 대체한다고 명시하고 있으며, 현재 대부분의 소셜 로그인과 API 권한 위임에서 OAuth 2.0이 사용된다. | ||
|
|
||
| OAuth 2.0은 HTTPS를 전제로 하며, OAuth 1.0처럼 매 요청마다 복잡한 서명을 직접 만드는 방식보다 구현이 단순하다. 또한 웹, 모바일 앱, SPA, 서버 간 통신 등 다양한 환경에 맞는 인증 흐름을 제공한다. | ||
|
|
||
| | 구분 | OAuth 1.0 | OAuth 2.0 | | ||
| | --- | --- | --- | | ||
| | 등장 시기 | 초기 방식 | OAuth 1.0 대체 | | ||
| | 보안 방식 | 요청마다 서명 필요 | HTTPS 기반 보호 | | ||
| | 구현 난이도 | 비교적 복잡 | 비교적 단순 | | ||
| | 토큰 방식 | Access Token 중심 | Access Token, Refresh Token 등 활용 | | ||
| | 사용 환경 | 초기 웹 중심 | 웹, 모바일, API 서버 등 다양함 | | ||
| | 현재 사용성 | 거의 안 쓰는 추세 | 현재 표준 | | ||
|
|
||
| OAuth 1.0은 요청마다 직접 서명을 만들어야 해서 보안적으로 엄격하지만 구현이 복잡하다. | ||
|
|
||
| OAuth 2.0은 HTTPS를 기반으로 보안을 확보하고, Access Token과 Refresh Token을 이용해 더 단순하고 유연한 구조를 제공한다. | ||
|
|
||
| 따라서 현재 카카오, 구글, 네이버 로그인 같은 소셜 로그인은 대부분 OAuth 2.0 기반으로 이해하면 된다. | ||
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -6,8 +6,15 @@ public record GetInfo( | |
| Long id | ||
| ){} | ||
|
|
||
| // 회원가입 | ||
| public record SignUp( | ||
| String email, | ||
| String password | ||
| ){} | ||
|
|
||
| // 로그인 | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 로그인과 회원가입 요청 DTO가 분리된 점은 적절합니다. 다음 단계에서는 |
||
| public record Login( | ||
| String email, | ||
| String password | ||
| ){} | ||
| } | ||
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
30 changes: 24 additions & 6 deletions
30
Jinyong/src/main/java/com/example/umc10th/domain/member/exception/code/MemberErrorCode.java
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,27 +1,45 @@ | ||
| package com.example.umc10th.domain.member.exception.code; | ||
|
|
||
| import com.example.umc10th.global.apiPayload.code.BaseErrorCode; | ||
| import lombok.AllArgsConstructor; | ||
| import lombok.Getter; | ||
| import org.springframework.http.HttpStatus; | ||
|
|
||
| @Getter | ||
| @AllArgsConstructor | ||
| public enum MemberErrorCode implements BaseErrorCode { | ||
|
|
||
| MEMBER_NOT_FOUND(HttpStatus.NOT_FOUND, | ||
| "MEMBER404", | ||
| "해당 사용자를 찾을 수 없습니다."), | ||
| MEMBER_ALREADY_EXISTS(HttpStatus.CONFLICT, | ||
| "MEMBER409_1", | ||
| "이미 존재하는 이메일입니다."); | ||
| "이미 존재하는 이메일입니다."), | ||
| INVALID_PASSWORD(HttpStatus.UNAUTHORIZED, | ||
| "MEMBER401_1", | ||
| "비밀번호가 일치하지 않습니다."), | ||
| NOT_SUPPORT_SOCIAL_PROVIDER(HttpStatus.BAD_REQUEST, | ||
| "MEMBER400_1", | ||
| "지원하지 않는 소셜 로그인 제공자입니다."); | ||
|
|
||
| private final HttpStatus httpStatus; | ||
| private final String code; | ||
| private final String message; | ||
|
|
||
| MemberErrorCode(HttpStatus httpStatus, String code, String message) { | ||
| this.httpStatus = httpStatus; | ||
| this.code = code; | ||
| this.message = message; | ||
| } | ||
|
|
||
| @Override | ||
| public HttpStatus getStatus() { | ||
| return httpStatus; | ||
| } | ||
| } | ||
|
|
||
| @Override | ||
| public String getCode() { | ||
| return code; | ||
| } | ||
|
|
||
| @Override | ||
| public String getMessage() { | ||
| return message; | ||
| } | ||
| } |
2 changes: 2 additions & 0 deletions
2
Jinyong/src/main/java/com/example/umc10th/domain/member/repository/MemberRepository.java
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,10 +1,12 @@ | ||
| package com.example.umc10th.domain.member.repository; | ||
|
|
||
| import com.example.umc10th.domain.member.entity.Member; | ||
| import com.example.umc10th.global.security.entity.SocialType; | ||
| import org.springframework.data.jpa.repository.JpaRepository; | ||
|
|
||
| import java.util.Optional; | ||
|
|
||
| public interface MemberRepository extends JpaRepository<Member, Long> { | ||
| Optional<Member> findByEmail(String email); | ||
| Optional<Member> findBySocialTypeAndSocialUid(SocialType socialType, String socialUid); | ||
| } |
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
OAuth2를 현재 표준이라고 정리한 점은 좋습니다. 추가로 Authorization Code Grant에서 Client, Authorization Server, Resource Server가 각각 어떤 책임을 가지는지 함께 정리하는 것을 권장합니다. 그러면 OAuth2가 단순한 소셜 로그인 구현이 아니라 권한 위임 프로토콜이라는 점이 더 명확해집니다.