Skip to content
Open
Show file tree
Hide file tree
Changes from 2 commits
Commits
Show all changes
27 commits
Select commit Hold shift + click to select a range
8b4d561
feat: [1단계] 테스트 적용하기
mangsuyo Jun 23, 2024
b832370
feat: [1단계] 로그인 요청시 토큰 발급
mangsuyo Jun 23, 2024
916b61e
feat: [1단계] 토큰 검증하기
mangsuyo Jun 23, 2024
814f977
feat: [2단계] 테스트 적용
mangsuyo Jun 23, 2024
728c6dd
feat: [2단계] 토큰으로 로그인하기
mangsuyo Jun 23, 2024
62dc582
feat: [2단계] 토큰으로 예약 생성하기
mangsuyo Jun 23, 2024
0169273
feat: [3단계] 테스트 적용하기
mangsuyo Jun 23, 2024
5db49d6
feat: [3단계] admin 페이지 인터셉터
mangsuyo Jun 23, 2024
c978b3c
refactor: [3단계] 구조 및 함수명 리팩터링
mangsuyo Jun 23, 2024
c9a3e42
refactor: 시크릿 키 감추기
mangsuyo Jun 30, 2024
36c3bcb
chore: [1단계] JPA 의존성 추가
mangsuyo Jun 30, 2024
a8ac74f
chore: [4단계] JPA 의존성 추가
mangsuyo Jun 30, 2024
5d62e8a
Merge branch 'mangsuyo-jpa' of https://github.com/mangsuyo/spring-bas…
mangsuyo Jun 30, 2024
d261be0
chore: [4단계] JPA 관련 설정
mangsuyo Jun 30, 2024
61e7358
feat: [4단계] 테스트 적용하기
mangsuyo Jun 30, 2024
4716b9d
feat: [4단계] 엔티티 매핑하기
mangsuyo Jun 30, 2024
047c001
feat: [4단계] 테스트 요구사항 해결하기
mangsuyo Jun 30, 2024
3d5715f
feat: [5단계] 테스트 적용하기
mangsuyo Jul 1, 2024
09128e0
feat: [5단계] jdbc -> jpa로 변경하기
mangsuyo Jul 1, 2024
931795a
feat: [5단계] 테스트 요구사항 해결하기
mangsuyo Jul 1, 2024
202c9ae
feat: [6단계] 테스트 적용하기
mangsuyo Jul 1, 2024
62ea442
feat: [6단계] 테스트 요구사항 해결하기
mangsuyo Jul 1, 2024
3641ab6
feat: 예약 대기 순서 전달하기
mangsuyo Jul 5, 2024
750a450
refactor: 예외 처리 반복 줄이기
mangsuyo Jul 5, 2024
181d65b
fix: 나의 예약에서 예약목록 반환하기
mangsuyo Jul 5, 2024
a71be85
feat: [7단계] jwtUtils 분리하기
mangsuyo Jul 9, 2024
fc94c7e
feat: [7단계] 프로필마다 데이터 주입하기
mangsuyo Jul 9, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
28 changes: 28 additions & 0 deletions src/main/java/roomescape/DataLoader.java
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.member.Member;
import roomescape.member.MemberRepository;

@Component
@Profile("product")
public class DataLoader implements CommandLineRunner {

private final MemberRepository memberRepository;

public DataLoader(MemberRepository memberRepository) {
this.memberRepository = memberRepository;

}

@Override
public void run(String... args) {
Member admin = new Member("어드민", "[email protected]", "password", "ADMIN");
Member brown = new Member("브라운", "[email protected]", "password", "USER");
memberRepository.save(admin);
memberRepository.save(brown);
}
}
66 changes: 66 additions & 0 deletions src/main/java/roomescape/TestDataLoader.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
package roomescape;

import java.util.Arrays;
import java.util.List;

import org.springframework.boot.CommandLineRunner;
import org.springframework.context.annotation.Profile;
import org.springframework.stereotype.Component;

import roomescape.member.Member;
import roomescape.member.MemberRepository;
import roomescape.reservation.Reservation;
import roomescape.reservation.ReservationRepository;
import roomescape.theme.Theme;
import roomescape.theme.ThemeRepository;
import roomescape.time.Time;
import roomescape.time.TimeRepository;

@Component
@Profile("test")
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
public void run(String... args) {
Member admin = new Member("어드민", "[email protected]", "password", "ADMIN");
Member brown = new Member("브라운", "[email protected]", "password", "USER");
memberRepository.saveAll(Arrays.asList(admin, brown));

Theme theme1 = new Theme("테마1", "테마1입니다.");
Theme theme2 = new Theme("테마2", "테마2입니다.");
Theme theme3 = new Theme("테마3", "테마3입니다.");
themeRepository.saveAll(Arrays.asList(theme1, theme2, theme3));

List<Time> times = Arrays.asList(
new Time("10:00"),
new Time("12:00"),
new Time("14:00"),
new Time("16:00"),
new Time("18:00"),
new Time("20:00")
);
timeRepository.saveAll(times);

Reservation reservation1 = new Reservation("admin", "2024-03-01", times.get(0), theme1);
Reservation reservation2 = new Reservation("admin", "2024-03-01", times.get(1), theme2);
Reservation reservation3 = new Reservation("admin", "2024-03-01", times.get(2), theme3);
Reservation reservation4 = new Reservation("brown", "2024-03-01", times.get(0), theme2);

reservationRepository.saveAll(Arrays.asList(reservation1, reservation2, reservation3, reservation4));
}
}


7 changes: 4 additions & 3 deletions src/main/java/roomescape/auth/AdminInterceptor.java
Original file line number Diff line number Diff line change
Expand Up @@ -5,23 +5,24 @@

import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import roomescape.jwt.JwtUtil;
import roomescape.member.Member;
import roomescape.member.MemberService;

@Component
public class AdminInterceptor implements HandlerInterceptor {

private MemberService memberService;
private final JwtUtils jwtUtils;

public AdminInterceptor(MemberService memberService) {
public AdminInterceptor(JwtUtils jwtUtils, MemberService memberService) {
this.jwtUtils = jwtUtils;
this.memberService = memberService;
}

@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws
Exception {
String token = JwtUtil.extractTokenFromCookie(request.getCookies());
String token = jwtUtils.extractTokenFromCookie(request.getCookies());
Member member = memberService.getMemberFromToken(token);
if (member == null || !member.getRole().equals("ADMIN")) {
response.setStatus(401);
Expand Down
17 changes: 17 additions & 0 deletions src/main/java/roomescape/auth/JwtConfiguration.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
package roomescape.auth;

import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

@Configuration
public class JwtConfiguration {

@Value("${roomescape.auth.jwt.secret}")
private String secretKey;

@Bean
public JwtUtils jwtUtils() {
return new JwtUtils();
}
}
Original file line number Diff line number Diff line change
@@ -1,25 +1,33 @@
package roomescape.jwt;
package roomescape.auth;

import java.util.Arrays;

import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;

import io.jsonwebtoken.Jwts;
import io.jsonwebtoken.security.Keys;
import jakarta.servlet.http.Cookie;
import roomescape.member.Member;

@Component
public class JwtUtil {
public class JwtUtils {

private static String secretKey;
private String secretKey;

@Value("${roomescape.auth.jwt.secret}")
public void setSecretKey(String secretKey) {
JwtUtil.secretKey = secretKey;
this.secretKey = secretKey;
}

public static String extractTokenFromCookie(Cookie[] cookies) {
public String createToken(Member member) {
return Jwts.builder()
.setSubject(member.getId().toString())
.claim("name", member.getName())
.claim("role", member.getRole())
.signWith(Keys.hmacShaKeyFor(secretKey.getBytes()))
.compact();
}

public String extractTokenFromCookie(Cookie[] cookies) {
if (cookies == null) {
throw new IllegalArgumentException("Cookies array is null");
}
Expand All @@ -31,7 +39,7 @@ public static String extractTokenFromCookie(Cookie[] cookies) {
.orElseThrow(() -> new IllegalArgumentException("Token cookie not found"));
}

public static Long getIdFromToken(String token) {
public Long getIdFromToken(String token) {
return Long.valueOf(Jwts.parserBuilder()
.setSigningKey(Keys.hmacShaKeyFor(secretKey.getBytes()))
.build()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,17 +9,18 @@

import jakarta.servlet.http.Cookie;
import jakarta.servlet.http.HttpServletRequest;
import roomescape.jwt.JwtUtil;
import roomescape.member.Member;
import roomescape.member.MemberService;

@Component
public class LoginMemberArgumentResolver implements HandlerMethodArgumentResolver {

private final MemberService memberService;
private final JwtUtils jwtUtils;

public LoginMemberArgumentResolver(MemberService memberService) {
public LoginMemberArgumentResolver(MemberService memberService, JwtUtils jwtUtils) {
this.memberService = memberService;
this.jwtUtils = jwtUtils;
}

@Override
Expand All @@ -32,7 +33,7 @@ public Object resolveArgument(MethodParameter parameter, ModelAndViewContainer m
NativeWebRequest webRequest, WebDataBinderFactory binderFactory) throws Exception {
HttpServletRequest request = webRequest.getNativeRequest(HttpServletRequest.class);
Cookie[] cookies = request.getCookies();
String token = JwtUtil.extractTokenFromCookie(cookies);
String token = jwtUtils.extractTokenFromCookie(cookies);
if (token == null) {
return null;
}
Expand Down
26 changes: 0 additions & 26 deletions src/main/java/roomescape/jwt/JwtProvider.java

This file was deleted.

9 changes: 6 additions & 3 deletions src/main/java/roomescape/member/MemberController.java
Original file line number Diff line number Diff line change
Expand Up @@ -11,13 +11,16 @@
import jakarta.servlet.http.Cookie;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import roomescape.jwt.JwtUtil;
import roomescape.auth.JwtUtils;

@RestController
public class MemberController {

private MemberService memberService;
private final JwtUtils jwtUtils;

public MemberController(MemberService memberService) {
public MemberController(JwtUtils jwtUtils, MemberService memberService) {
this.jwtUtils = jwtUtils;
this.memberService = memberService;
}

Expand All @@ -39,7 +42,7 @@ public void login(@RequestBody MemberLoginRequest request, HttpServletResponse r
@GetMapping("/login/check")
public MemberCheckResponse checkLogin(HttpServletRequest request) {
Cookie[] cookies = request.getCookies();
String token = JwtUtil.extractTokenFromCookie(cookies);
String token = jwtUtils.extractTokenFromCookie(cookies);
return memberService.checkMember(token);
}

Expand Down
15 changes: 7 additions & 8 deletions src/main/java/roomescape/member/MemberService.java
Original file line number Diff line number Diff line change
Expand Up @@ -3,34 +3,33 @@
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import roomescape.jwt.JwtProvider;
import roomescape.jwt.JwtUtil;
import roomescape.auth.JwtUtils;

@Service
public class MemberService {

private final MemberRepository memberRepository;
private final JwtProvider jwtProvider;
private final JwtUtils jwtUtils;

@Autowired
public MemberService(MemberRepository memberRepository, JwtProvider jwtProvider) {
public MemberService(MemberRepository memberRepository, JwtUtils jwtUtils) {
this.memberRepository = memberRepository;
this.jwtProvider = jwtProvider;
this.jwtUtils = jwtUtils;
}

public String login(MemberLoginRequest request) {
Member member = memberRepository.getByEmailAndPassword(request.email(), request.password());
return jwtProvider.createToken(member);
return jwtUtils.createToken(member);
}

public MemberCheckResponse checkMember(String token) {
Long memberId = JwtUtil.getIdFromToken(token);
Long memberId = jwtUtils.getIdFromToken(token);
Member member = memberRepository.getById(memberId);
return new MemberCheckResponse(member.getName());
}

public Member getMemberFromToken(String token) {
Long memberId = JwtUtil.getIdFromToken(token);
Long memberId = jwtUtils.getIdFromToken(token);
return memberRepository.findById(memberId).orElseThrow(() -> new IllegalArgumentException("Invalid member"));
}

Expand Down
3 changes: 3 additions & 0 deletions src/main/resources/application.properties
Original file line number Diff line number Diff line change
Expand Up @@ -7,3 +7,6 @@ spring.jpa.show-sql=true
spring.jpa.properties.hibernate.format_sql=true
spring.jpa.ddl-auto=create-drop
spring.jpa.defer-datasource-initialization=true
spring.profiles.active=product


25 changes: 0 additions & 25 deletions src/main/resources/data.sql

This file was deleted.

9 changes: 9 additions & 0 deletions src/test/java/roomescape/JpaTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@

import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.test.autoconfigure.orm.jpa.DataJpaTest;
import org.springframework.boot.test.autoconfigure.orm.jpa.TestEntityManager;

Expand All @@ -18,6 +19,9 @@ public class JpaTest {
@Autowired
private TimeRepository timeRepository;

@Value("${roomescape.auth.jwt.secret}")
private String secretKey;

@Test
void 사단계() {
Time time = new Time("10:00");
Expand All @@ -28,5 +32,10 @@ public class JpaTest {

assertThat(persistTime.getTime()).isEqualTo(time.getTime());
}

@Test
void 팔단계() {
assertThat(secretKey).isNotBlank();
}
}

Loading