-
Notifications
You must be signed in to change notification settings - Fork 78
[Spring Core] (배포) 신지훈 미션 제출합니다. #115
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
developowl
wants to merge
92
commits into
next-step:0094-gengar
Choose a base branch
from
developowl:Core
base: 0094-gengar
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
Changes from 80 commits
Commits
Show all changes
92 commits
Select commit
Hold shift + click to select a range
5a89792
refactor(MissionStepTest): [1단계] 일단계 테스트 코드 추가
developowl acd8813
feat(TokenRequest): [1단계] 사용자 로그인 요청 DTO 생성
developowl 013c8a8
feat(TokenLoginController): [1단계] 사용자 인증 및 로그인 요청 처리 기능 추가(tokenLogin)
developowl 3569c13
feat(AuthService): [1단계] 사용자 인증 처리 클래스 생성
developowl 1ddb5a4
feat(JwtTokenProvider): [1단계] 토큰 생성 및 검증 클래스 생성
developowl 6cf51d4
refactor(MemberDao): [1단계] email로 사용자를 찾는 메서드 추가(findByEmail)
developowl 1f22ed7
feat(TokenResponse): [1단계] 로그인 응답 클래스 생성
developowl ee6dac0
refactor(TokenLoginController): [1단계] 사용자 인증 상태 확인 요청 기능 추가(checkLogin)
developowl 91bd50f
feat(BearerAuthorizationExtractor): [1단계] Bearer 토큰 추출 클래스 추가
developowl e7c9b87
feat(AuthorizationExtractor): [1단계] 인증 정보 추출을 위한 인터페이스 생성
developowl 7773f89
feat(AuthorizationExtractor): [1단계] 인증 관련 예외 처리 클래스 생성
developowl aa6384d
refactor(AuthService): [1단계] 인증 실패 예외처리 통일
developowl 42c9296
refactor(application.properties): [1단계] jwt properties 추가
developowl e39fa6e
refactor(TokenLoginController): [1단계] 코드 문법 수정(로직 동일)
developowl 12e4981
refactor(MissionStepTest): [2단계] 이단계 테스트 코드 추가 및 토큰 추출 메서드 생성
developowl 084f339
feat(LoginMemberArgumentResolver): [2단계] 쿠키를 통해 멤버 정보를 조회하는 ArgumentR…
developowl a9d0815
feat(LoginMember): [2단계] LoginMemberArgumentResolver 를 통해 조회한 멤버 정보를 …
developowl 75870e3
refactor(AuthService): [2단계] 이메일로 멤버를 조회하는 메서드의 반환형 변경(MemberResponse…
developowl 1ad00b6
refactor(TokenLoginController): [2단계] loginMember 를 통해 전달된 정보를 응답으로 바…
developowl 6562345
refactor(ReservationController): [2단계] name이 없는 경우 Cookie에 담긴 정보를 활용하…
developowl c9a7b9c
refactor(ReservationRequest): [2단계] DB에서 회원 데이터를 조회하기 위해 memberId 필드 추가
developowl 96df506
refactor(MissionStepTest): [3단계] 삼단계 테스트 코드 추가
developowl 1021263
feat(WebConfig): WebConfig 추가(Resolvers, interceptors)
developowl 0dd51e8
feat(AdminAccessInterceptor): [3단계] Interceptor 생성
developowl 59aecdc
[질문]: build.gradle
developowl 7622e3f
주석 및 공백 정리
developowl d09b798
refactor(build.gradle): [4단계] jdbc -> jpa 의존성 변경
developowl 999bca1
refactor(application.properties): [4단계] jpa 의존성 추가
developowl aad687f
refactor(Dao): [4단계] 전체 DAO 클래스 삭제
developowl 7d9cead
feat(TimeRepository): [4단계] Dao -> TimeRepository 생성
developowl 920de2e
refactor(TimeService): [4단계] Dao -> Repository 로직 변경
developowl c7b5651
refactor(TimeController): [4단계] 메서드명 변경(getValue -> getTime)
developowl 664d873
refactor(Theme): [4단계] Theme 클래스 엔티티 설정 및 매핑
developowl 4e6e0e2
feat(ThemeRepository): [4단계] Dao -> ThemeRepository 생성
developowl d2d7c24
refactor(ThemeController): [4단계] Dao -> Repository 방식으로 리팩토링
developowl 880c053
feat(MemberRepository): [4단계] Dao -> MemberRepository 생성
developowl 1694a87
refactor(Member): [4단계] Member 클래스 엔티티 설정 및 매핑
developowl 2478292
refactor(MemberService): [4단계] Dao -> Repository 로직 변경
developowl b767ae7
refactor(AuthService): [4단계] Dao -> Repository 로직 변경
developowl 357734e
feat(ReservationRepository): [4단계] Dao -> ReservationRepository 생성
developowl 56d04ca
refactor(Reservation): [4단계] Reservation 클래스 엔티티 설정 및 매핑
developowl 85c6191
refactor(Reservation): [4단계] Request, Response 필드 변수 자료형 변경(String ->…
developowl e74ba1b
refactor(Reservation): [4단계] Dao -> Repository 로직 변경
developowl 3ccbabf
refactor(schema.sql): [4단계] 테이블 생성 구문 삭제(hibernate와 중복 생성 때문)
developowl f348d60
refactor(MissionStepTest): [4단계] 사단계 테스트 코드 추가
developowl ca6e81a
refactor(MissionStepTest): [5단계] 오단계 테스트 코드 추가
developowl 6b03aaf
refactor(MissionStepTest): 테스트 코드 추가(사단계, 오단계)
developowl 6f22cb2
1~4단계: 오류 정리 및 리팩토링(다시 시작..)
developowl 8ede4af
1~4단계: 오류 정리 및 리팩토링 2(다시 시작..)
developowl 595ad00
refactor(MissionStepTest): [5단계] 오단계 테스트 코드 추가
developowl 68af541
refactor(schema): [5단계] 초기값 설정 쿼리 수정
developowl a5e4367
feat(MyReservationResponse): [5단계] 내 예약 조회 DTO 추가
developowl 3244cf2
refactor(ReservationRepository): [5단계] findByName 메서드 등록
developowl abd6f42
refactor(ReservationService): [5단계] 내 예약 조회 로직 생성
developowl e194f03
refactor(ReservationController): [5단계] 내 예약 조회 API 생성
developowl d003cbc
refactor(MissionStepTest): [6단계] 육단계 테스트 코드 추가
developowl f973982
feat(DuplicateReservationException): [6단계] 중복 예약 커스텀 예외 생성
developowl aa3847d
feat(Waiting): [6단계] 예약 대기 엔티티 생성
developowl 5360403
feat(WaitingWithRank): [6단계] 예약 대기(순번 추가) 객체 생성
developowl 2735245
feat(WaitingRequest / Response): [6단계] 예약 대기 요청, 응답 생성
developowl 6eb5491
feat(WaitingRepository): [6단계] WaitingRepository 생성
developowl 664156b
feat(WaitingService): [6단계] 예약대기 서비스 생성
developowl c66e0cd
feat(WaitingController): [6단계] 예약대기 컨트롤러 생성
developowl f030098
refactor(ReservationRepository): [6단계] exist 메서드 추가
developowl 7198357
refactor(ReservationService): [6단계] 예약 대기 목록 조회 추가(내 예약 목록 조회 시)
developowl 14c6c64
refactor(ReservationController): [6단계] 컨트롤러 리팩토링
developowl d0c428b
EOL, 미사용 코드, 주석 정리
developowl 77f696e
refactor(ReservationController, Service): 컨트롤러 내 서비스 로직 이동
developowl 8678ade
refactor(AuthService): checkInvalidLogin을 void 함수로 변경
developowl 302a34e
refactor(AuthService): verifyToken메서드를 void형으로 변경
developowl 883e77e
refactor(MissionStep): [7단계] 칠단계 테스트 코드 추가
developowl 771bf97
fix conflicts
developowl 4a9786c
refactor(MissionStepTest): [7단계] 칠단계 테스트 코드 추가
developowl 764196a
refactor: [7단계] 반영
developowl 01d4875
refactor: 로그인 로직 리팩토링
developowl 4554a5d
refactor(MissionStepTest): [8단계] 팔단계 테스트 코드 추가
developowl f434739
refactor(properties): [8단계] environment 분리(default, prod, test)
developowl 2966054
feat(DataLoader): [8단계] schema.sql -> DataLoader 형식으로 변경
developowl 631456a
refactor(JwtAuthManager): bean 충돌 해결
developowl abdef60
refactor: 기존 오류 및 로직 리팩토링
developowl 869a52e
refactor: 미사용 코드 및 주석 삭제
developowl bc3e5f2
conflict fix
developowl 86fed55
refactor(build.gradle): jar 블록 추가
developowl bcd7d76
refactor: prod.properties 수정
developowl 9906c22
미사용 코드 삭제
developowl 7db3c6a
refactor: DTO -> record 형으로 변경. ReservationRequest, WaitingRequest는 s…
developowl 80bbdc7
refactor: 패키지 분리에 따른 클래스 이동 및 미사용 클래스 삭제(move: JwtAuthConfig, delete:…
developowl b3560ce
refactor: 미사용 클래스 삭제(AuthorizationExtractor)
developowl 181153b
docs(README.md): 패키지 구분 및 역할 명시
developowl a8290d8
refactor(TestDataLoader): test 패키지로 이동
developowl 701263e
refactor: ArgumentResolver에서 멤버 조회 후 id값만 갖는 객체를 반환하게끔 리팩토링
developowl 5957d4e
refactor: 의존성이 한방향으로 흐르게끔 코드 수정
developowl 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,47 @@ | ||
| package auth; | ||
|
|
||
| import jakarta.servlet.http.Cookie; | ||
| import jakarta.servlet.http.HttpServletRequest; | ||
| import jakarta.servlet.http.HttpServletResponse; | ||
| import org.springframework.stereotype.Component; | ||
| import org.springframework.web.servlet.HandlerInterceptor; | ||
| import roomescape.exception.AuthorizationException; | ||
|
|
||
| import java.util.Arrays; | ||
|
|
||
| @Component | ||
| public class AdminAccessInterceptor implements HandlerInterceptor { | ||
| private final JwtAuthManager jwtAuthManager; | ||
|
|
||
| public AdminAccessInterceptor(JwtAuthManager jwtAuthManager) { | ||
| this.jwtAuthManager = jwtAuthManager; | ||
| } | ||
|
|
||
| @Override | ||
| public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception { | ||
| String token = extractTokenFromCookies(request.getCookies()); | ||
| jwtAuthManager.validateToken(token); | ||
|
|
||
| String role = jwtAuthManager.getRole(token); | ||
|
|
||
| if (!"ADMIN".equals(role)) { | ||
| response.setStatus(401); | ||
| response.getWriter().write("권한이 없습니다."); | ||
| return false; | ||
| } | ||
|
|
||
| return true; | ||
| } | ||
|
|
||
| private String extractTokenFromCookies(Cookie[] cookies) { | ||
| if (cookies == null) { | ||
| throw new AuthorizationException("쿠키가 존재하지 않습니다."); | ||
| } | ||
|
|
||
| return Arrays.stream(cookies) | ||
| .filter(cookie -> "token".equals(cookie.getName())) | ||
| .findFirst() | ||
| .map(Cookie::getValue) | ||
| .orElseThrow(() -> new AuthorizationException("토큰 쿠키가 없습니다.")); | ||
| } | ||
| } |
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,94 @@ | ||
| package auth; | ||
|
|
||
| import io.jsonwebtoken.*; | ||
| import org.springframework.beans.factory.annotation.Value; | ||
| import roomescape.domain.member.Member; | ||
| import roomescape.domain.member.MemberRepository; | ||
| import roomescape.exception.AuthorizationException; | ||
|
|
||
| import java.util.Date; | ||
|
|
||
| public class JwtAuthManager { | ||
|
|
||
| @Value("${roomescape.auth.jwt.secret}") | ||
| private String secretKey; | ||
|
|
||
| @Value("${roomescape.auth.jwt.expire-length}") | ||
| private long validityInMilliseconds; | ||
|
|
||
| private final MemberRepository memberRepository; | ||
|
|
||
| public JwtAuthManager(MemberRepository memberRepository) { | ||
| this.memberRepository = memberRepository; | ||
| } | ||
|
|
||
| public String createToken(String email, String password) { | ||
| Member member = memberRepository.findByEmailAndPassword(email, password) | ||
| .orElseThrow(() -> new AuthorizationException("유효한 이메일이 아닙니다.")); | ||
|
|
||
| Long memberId = member.getId(); | ||
| String role = member.getRole(); | ||
|
|
||
| Claims claims = Jwts.claims().setSubject(String.valueOf(memberId)); | ||
| claims.put("role", role); | ||
|
|
||
| Date now = new Date(); | ||
| Date validity = new Date(now.getTime() + validityInMilliseconds); | ||
|
|
||
| return Jwts.builder() | ||
| .setClaims(claims) | ||
| .setIssuedAt(now) | ||
| .setExpiration(validity) | ||
| .signWith(SignatureAlgorithm.HS256, secretKey) | ||
| .compact(); | ||
| } | ||
|
|
||
| public Long getId(String token) { | ||
| JwtParser parser = Jwts.parserBuilder() | ||
| .setSigningKey(secretKey) | ||
| .build(); | ||
|
|
||
| Claims claims = parser.parseClaimsJws(token).getBody(); | ||
| return Long.parseLong(claims.getSubject()); | ||
| } | ||
|
|
||
| public String getRole(String token) { | ||
| JwtParser parser = Jwts.parserBuilder() | ||
| .setSigningKey(secretKey) | ||
| .build(); | ||
|
|
||
| Claims claims = parser.parseClaimsJws(token).getBody(); | ||
| return claims.get("role", String.class); | ||
| } | ||
|
|
||
| public void validateToken(String token) { | ||
| try { | ||
| Jws<Claims> claims = Jwts.parser().setSigningKey(secretKey).parseClaimsJws(token); | ||
|
|
||
| if (claims.getBody().getExpiration().before(new Date())) { | ||
|
|
||
| throw new IllegalArgumentException("토큰이 만료되었습니다."); | ||
| } | ||
| } catch (JwtException | IllegalArgumentException e) { | ||
| throw new IllegalArgumentException("유효하지 않은 토큰입니다.", e); | ||
| } | ||
| } | ||
|
|
||
| // public String getName(String token) { | ||
| // JwtParser parser = Jwts.parserBuilder() | ||
| // .setSigningKey(secretKey) | ||
| // .build(); | ||
| // | ||
| // Claims claims = parser.parseClaimsJws(token).getBody(); | ||
| // return claims.get("name", String.class); | ||
| // } | ||
| // | ||
| // public String getEmail(String token) { | ||
| // JwtParser parser = Jwts.parserBuilder() | ||
| // .setSigningKey(secretKey) | ||
| // .build(); | ||
| // | ||
| // Claims claims = parser.parseClaimsJws(token).getBody(); | ||
| // return claims.get("email", String.class); | ||
| // } | ||
| } | ||
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,67 @@ | ||
| package auth; | ||
|
|
||
| import jakarta.servlet.http.Cookie; | ||
| import jakarta.servlet.http.HttpServletRequest; | ||
| import org.springframework.core.MethodParameter; | ||
| import org.springframework.web.bind.support.WebDataBinderFactory; | ||
| import org.springframework.web.context.request.NativeWebRequest; | ||
| import org.springframework.web.method.support.HandlerMethodArgumentResolver; | ||
| import org.springframework.web.method.support.ModelAndViewContainer; | ||
| import roomescape.domain.member.MemberRepository; | ||
| import roomescape.exception.AuthorizationException; | ||
| import roomescape.domain.member.Member; | ||
|
|
||
| import java.util.Arrays; | ||
|
|
||
| public class LoginMemberArgumentResolver implements HandlerMethodArgumentResolver { | ||
| private final JwtAuthManager jwtAuthManager; | ||
| private final MemberRepository memberRepository; | ||
|
|
||
| public LoginMemberArgumentResolver(JwtAuthManager jwtAuthManager, MemberRepository memberRepository) { | ||
| this.jwtAuthManager = jwtAuthManager; | ||
| this.memberRepository = memberRepository; | ||
| } | ||
|
|
||
| @Override | ||
| public boolean supportsParameter(MethodParameter parameter) { | ||
| return parameter.getParameterType().equals(Member.class); | ||
| } | ||
developowl marked this conversation as resolved.
Show resolved
Hide resolved
|
||
|
|
||
| @Override | ||
| public Object resolveArgument(MethodParameter parameter, | ||
| ModelAndViewContainer mavContainer, | ||
| NativeWebRequest webRequest, | ||
| WebDataBinderFactory binderFactory) throws Exception { | ||
| HttpServletRequest request = (HttpServletRequest) webRequest.getNativeRequest(); | ||
|
|
||
| String token = extractTokenFromCookies(request.getCookies()); | ||
| jwtAuthManager.validateToken(token); | ||
|
|
||
| Long id = jwtAuthManager.getId(token); | ||
|
|
||
| Member member = memberRepository.findById(id) | ||
| .orElseThrow(() -> new AuthorizationException("Member not found")); | ||
|
|
||
| String name = member.getName(); | ||
|
|
||
| String email = member.getEmail(); | ||
|
|
||
| String password = member.getPassword(); | ||
|
|
||
| String role = jwtAuthManager.getRole(token); | ||
|
|
||
| return new Member(id, name, email, password, role); | ||
| } | ||
developowl marked this conversation as resolved.
Show resolved
Hide resolved
|
||
|
|
||
| private String extractTokenFromCookies(Cookie[] cookies) { | ||
| if (cookies == null) { | ||
| throw new AuthorizationException("쿠키가 존재하지 않습니다."); | ||
| } | ||
|
|
||
| return Arrays.stream(cookies) | ||
| .filter(cookie -> "token".equals(cookie.getName())) | ||
| .findFirst() | ||
| .map(Cookie::getValue) | ||
| .orElseThrow(() -> new AuthorizationException("토큰 쿠키가 없습니다.")); | ||
| } | ||
| } | ||
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,28 @@ | ||
| package roomescape; | ||
|
|
||
| import org.springframework.boot.CommandLineRunner; | ||
| import org.springframework.context.annotation.Profile; | ||
| import org.springframework.stereotype.Component; | ||
| import roomescape.domain.member.Member; | ||
| import roomescape.domain.member.MemberRepository; | ||
|
|
||
| @Profile("default") // 배포 환경 -> "prod", 로컬 환경 -> "default" | ||
| @Component | ||
| public class DataLoader implements CommandLineRunner { | ||
| private final MemberRepository memberRepository; | ||
|
|
||
| public DataLoader(MemberRepository memberRepository) { | ||
| this.memberRepository = memberRepository; | ||
| } | ||
|
|
||
| @Override | ||
| public void run(String... args) throws Exception { | ||
| if (memberRepository.count() == 0) { | ||
| Member admin = new Member("어드민", "[email protected]", "password", "ADMIN"); | ||
| Member brown = new Member("브라운", "[email protected]", "password", "USER"); | ||
| memberRepository.save(admin); | ||
| memberRepository.save(brown); | ||
| System.out.println("초기 사용자 정보가 등록되었습니다."); | ||
| } | ||
| } | ||
| } |
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,57 @@ | ||
| package roomescape; | ||
|
|
||
| import org.springframework.boot.CommandLineRunner; | ||
| import org.springframework.context.annotation.Profile; | ||
| import org.springframework.stereotype.Component; | ||
| import org.springframework.transaction.annotation.Transactional; | ||
| import roomescape.domain.member.Member; | ||
| import roomescape.domain.member.MemberRepository; | ||
| import roomescape.domain.theme.Theme; | ||
| import roomescape.domain.theme.ThemeRepository; | ||
| import roomescape.domain.time.Time; | ||
| import roomescape.domain.time.TimeRepository; | ||
| import roomescape.domain.reservation.Reservation; | ||
| import roomescape.domain.reservation.ReservationRepository; | ||
|
|
||
| @Profile("test") | ||
| @Component | ||
| public class TestDataLoader implements CommandLineRunner { | ||
| private final MemberRepository memberRepository; | ||
| private final ThemeRepository themeRepository; | ||
| private final TimeRepository timeRepository; | ||
| private final ReservationRepository reservationRepository; | ||
|
|
||
| public TestDataLoader(MemberRepository memberRepository, ThemeRepository themeRepository, | ||
| TimeRepository timeRepository, ReservationRepository reservationRepository) { | ||
| this.memberRepository = memberRepository; | ||
| this.themeRepository = themeRepository; | ||
| this.timeRepository = timeRepository; | ||
| this.reservationRepository = reservationRepository; | ||
| } | ||
|
|
||
| @Override | ||
| @Transactional | ||
| public void run(String... args) throws Exception { | ||
| Member admin = new Member("어드민", "[email protected]", "password", "ADMIN"); | ||
| Member brown = new Member("브라운", "[email protected]", "password", "USER"); | ||
| memberRepository.save(admin); | ||
| memberRepository.save(brown); | ||
|
|
||
| Theme theme1 = new Theme("테마1", "테마1입니다."); | ||
| Theme theme2 = new Theme("테마2", "테마2입니다."); | ||
| themeRepository.save(theme1); | ||
| themeRepository.save(theme2); | ||
|
|
||
| Time time1 = new Time("10:00"); | ||
| Time time2 = new Time("12:00"); | ||
| timeRepository.save(time1); | ||
| timeRepository.save(time2); | ||
|
|
||
| Reservation reservation1 = new Reservation("어드민", "2024-03-01", time1, theme1, admin); | ||
| Reservation reservation2 = new Reservation("브라운", "2024-03-01", time2, theme2, brown); | ||
| reservationRepository.save(reservation1); | ||
| reservationRepository.save(reservation2); | ||
|
|
||
| System.out.println("테스트 데이터가 초기화되었습니다."); | ||
| } | ||
| } | ||
developowl marked this conversation as resolved.
Show resolved
Hide resolved
|
||
9 changes: 9 additions & 0 deletions
9
src/main/java/roomescape/authentication/AuthorizationExtractor.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 |
|---|---|---|
| @@ -0,0 +1,9 @@ | ||
| package roomescape.authentication; | ||
|
|
||
| import jakarta.servlet.http.HttpServletRequest; | ||
|
|
||
| public interface AuthorizationExtractor<T> { | ||
| String AUTHORIZATION = "Authorization"; | ||
|
|
||
| T extract(HttpServletRequest request); | ||
| } |
28 changes: 28 additions & 0 deletions
28
src/main/java/roomescape/authentication/BearerAuthorizationExtractor.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 |
|---|---|---|
| @@ -0,0 +1,28 @@ | ||
| package roomescape.authentication; | ||
|
|
||
| import jakarta.servlet.http.HttpServletRequest; | ||
|
|
||
| import java.util.Enumeration; | ||
|
|
||
| public class BearerAuthorizationExtractor implements AuthorizationExtractor<String> { | ||
| private static final String BEARER_TYPE = "Bearer"; | ||
| private static final String ACCESS_TOKEN_TYPE = BearerAuthorizationExtractor.class.getSimpleName() + ".ACCESS_TOKEN_TYPE"; | ||
|
|
||
| @Override | ||
| public String extract(HttpServletRequest request) { | ||
| Enumeration<String> headers = request.getHeaders(AUTHORIZATION); | ||
| while (headers.hasMoreElements()) { | ||
| String value = headers.nextElement(); | ||
| if ((value.toLowerCase().startsWith(BEARER_TYPE.toLowerCase()))) { | ||
| String authHeaderValue = value.substring(BEARER_TYPE.length()).trim(); | ||
| request.setAttribute(ACCESS_TOKEN_TYPE, value.substring(0, BEARER_TYPE.length()).trim()); | ||
| int commaIndex = authHeaderValue.indexOf(','); | ||
| if (commaIndex > 0) { | ||
| authHeaderValue = authHeaderValue.substring(0, commaIndex); | ||
| } | ||
| return authHeaderValue; | ||
| } | ||
| } | ||
| return null; | ||
| } | ||
| } |
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,22 @@ | ||
| package roomescape.config; | ||
|
|
||
| import auth.JwtAuthManager; | ||
| import org.springframework.context.annotation.Bean; | ||
| import org.springframework.context.annotation.ComponentScan; | ||
| import org.springframework.context.annotation.Configuration; | ||
| import roomescape.domain.member.MemberRepository; | ||
|
|
||
| @Configuration | ||
| @ComponentScan(basePackages = {"roomescape", "auth"}) | ||
| public class JwtAuthConfig { | ||
| private final MemberRepository memberRepository; | ||
|
|
||
| public JwtAuthConfig(MemberRepository memberRepository) { | ||
| this.memberRepository = memberRepository; | ||
| } | ||
|
|
||
| @Bean | ||
| public JwtAuthManager jwtAuthManager() { | ||
| return new JwtAuthManager(memberRepository); | ||
| } | ||
| } | ||
developowl marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||
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.
Uh oh!
There was an error while loading. Please reload this page.