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

[Spring Core] 최규원 미션 제출합니다. #74

Open
wants to merge 22 commits into
base: kyuwon-choi
Choose a base branch
from
Open
Changes from 1 commit
Commits
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
Prev Previous commit
Next Next commit
step 2
Kyuwon-Choi committed Jun 24, 2024
commit b13970c3b76bc1e176eae80c004700ee7aa43bd1
1 change: 1 addition & 0 deletions build.gradle
Original file line number Diff line number Diff line change
@@ -22,6 +22,7 @@ dependencies {
implementation 'io.jsonwebtoken:jjwt-api:0.11.2'
implementation 'io.jsonwebtoken:jjwt-impl:0.11.2'
implementation 'io.jsonwebtoken:jjwt-gson:0.11.2'
implementation 'org.projectlombok:lombok:1.18.22'

testImplementation 'org.springframework.boot:spring-boot-starter-test'
testImplementation 'io.rest-assured:rest-assured:5.3.1'
34 changes: 34 additions & 0 deletions src/main/java/roomescape/auth/LoginMemberArgumentResolver.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
package roomescape.auth;

import jakarta.servlet.http.HttpServletRequest;
import org.springframework.core.MethodParameter;
import org.springframework.stereotype.Component;
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.member.LoginMember;
import roomescape.member.Member;
import roomescape.member.MemberService;

@Component
public class LoginMemberArgumentResolver implements HandlerMethodArgumentResolver {
private MemberService memberService;

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

@Override
public boolean supportsParameter(MethodParameter parameter) {
return parameter.getParameterType().equals(LoginMember.class);
}

@Override
public Object resolveArgument(MethodParameter parameter, ModelAndViewContainer mavContainer, NativeWebRequest webRequest, WebDataBinderFactory binderFactory) throws Exception {
HttpServletRequest request = (HttpServletRequest) webRequest.getNativeRequest();
String token = memberService.extractTokenFromCookie(request.getCookies());
Member member = memberService.findByToken(token);
return new LoginMember(member.getId(), member.getName(), member.getEmail(), member.getRole());
}
}
11 changes: 11 additions & 0 deletions src/main/java/roomescape/auth/LoginResolver.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
package roomescape.auth;

import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

@Target(ElementType.PARAMETER)
@Retention(RetentionPolicy.RUNTIME)
public @interface LoginResolver {
}
20 changes: 20 additions & 0 deletions src/main/java/roomescape/auth/WebConfig.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
package roomescape.auth;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.method.support.HandlerMethodArgumentResolver;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;

import java.util.List;

@Configuration
public class WebConfig implements WebMvcConfigurer {

@Autowired
private LoginMemberArgumentResolver loginMemberArgumentResolver;

@Override
public void addArgumentResolvers(List<HandlerMethodArgumentResolver> argumentResolvers) {
argumentResolvers.add(loginMemberArgumentResolver);
}
}
20 changes: 20 additions & 0 deletions src/main/java/roomescape/member/LoginMember.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
package roomescape.member;

import lombok.Getter;
import lombok.Setter;

@Getter
@Setter
public class LoginMember {
private Long id;
private String name;
private String email;
private String role;

public LoginMember(Long id, String name, String email, String role) {
this.id = id;
this.name = name;
this.email = email;
this.role = role;
}
}
7 changes: 4 additions & 3 deletions src/main/java/roomescape/member/MemberController.java
Original file line number Diff line number Diff line change
@@ -28,7 +28,7 @@ public ResponseEntity createMember(@RequestBody MemberRequest memberRequest) {
}
@PostMapping("/login")
public ResponseEntity login(@RequestBody MemberRequest memberRequest, HttpServletResponse response) {
MemberResponse member = memberService.findMemberByEmailAndPassword(memberRequest.getEmail(), memberRequest.getPassword());
Member member = memberService.findMemberByEmailAndPassword(memberRequest.getEmail(), memberRequest.getPassword());
if (member == null) {
return ResponseEntity.badRequest().build();
}
@@ -47,8 +47,9 @@ public ResponseEntity<MemberResponse> checkLogin(HttpServletRequest request) {
return ResponseEntity.badRequest().build();
}
String token = memberService.extractTokenFromCookie(cookies);
MemberResponse member = memberService.findByToken(token);
return ResponseEntity.ok(member);
Member member = memberService.findByToken(token);
MemberResponse memberResponse = new MemberResponse(member.getId(), member.getName(), member.getEmail());
return ResponseEntity.ok(memberResponse);
}


13 changes: 6 additions & 7 deletions src/main/java/roomescape/member/MemberService.java
Original file line number Diff line number Diff line change
@@ -3,7 +3,6 @@
import io.jsonwebtoken.Jwts;
import io.jsonwebtoken.security.Keys;
import jakarta.servlet.http.Cookie;
import kotlin.reflect.jvm.internal.impl.descriptors.Visibilities;
import org.springframework.stereotype.Service;
import roomescape.provider.TokenProvider;

@@ -20,15 +19,15 @@ public MemberResponse createMember(MemberRequest memberRequest) {
return new MemberResponse(member.getId(), member.getName(), member.getEmail());
}

public MemberResponse findMemberByEmailAndPassword(String email, String password) {
public Member findMemberByEmailAndPassword(String email, String password) {
Member member = memberDao.findByEmailAndPassword(email, password);
return new MemberResponse(member.getId(), member.getName(), member.getEmail());
return member;
}
public String createToken(MemberResponse member) {
public String createToken(Member member) {
String accessToken = TokenProvider.createToken(member);
return accessToken;
}
String extractTokenFromCookie(Cookie[] cookies) {
public String extractTokenFromCookie(Cookie[] cookies) {
for (Cookie cookie : cookies) {
if (cookie.getName().equals("token")) {
return cookie.getValue();
@@ -38,13 +37,13 @@ String extractTokenFromCookie(Cookie[] cookies) {
return "";
}

public MemberResponse findByToken(String token) {
public Member findByToken(String token) {
Long memberId = Long.valueOf(Jwts.parserBuilder()
.setSigningKey(Keys.hmacShaKeyFor("Yn2kjibddFAWtnPJ2AFlL8WXmohJMCvigQggaEypa5E=".getBytes()))
.build()
.parseClaimsJws(token)
.getBody().getSubject());
Member member = memberDao.findById(memberId);
return new MemberResponse(member.getId(), member.getName(), member.getEmail());
return member;
}
}
4 changes: 3 additions & 1 deletion src/main/java/roomescape/provider/TokenProvider.java
Original file line number Diff line number Diff line change
@@ -3,16 +3,18 @@
import io.jsonwebtoken.Jwts;
import io.jsonwebtoken.security.Keys;
import org.springframework.stereotype.Component;
import roomescape.member.Member;
import roomescape.member.MemberResponse;

@Component
public class TokenProvider {
public static String createToken(MemberResponse member) {
public static String createToken(Member member) {
String secretKey = "Yn2kjibddFAWtnPJ2AFlL8WXmohJMCvigQggaEypa5E=";
String accessToken = Jwts.builder()
.setSubject(member.getId().toString())
.claim("name", member.getName())
.claim("email", member.getEmail())
.claim("role", member.getRole())
.signWith(Keys.hmacShaKeyFor(secretKey.getBytes()))
.compact();
return accessToken;
Original file line number Diff line number Diff line change
@@ -7,6 +7,7 @@
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RestController;
import roomescape.member.LoginMember;

import java.net.URI;
import java.util.List;
@@ -26,9 +27,11 @@ public List<ReservationResponse> list() {
}

@PostMapping("/reservations")
public ResponseEntity create(@RequestBody ReservationRequest reservationRequest) {
if (reservationRequest.getName() == null
|| reservationRequest.getDate() == null
public ResponseEntity create(@RequestBody ReservationRequest reservationRequest, LoginMember member) {
if(reservationRequest.getName() == null && member != null){
reservationRequest.setName(member.getName());
}
if ( reservationRequest.getDate() == null
|| reservationRequest.getTheme() == null
|| reservationRequest.getTime() == null) {
return ResponseEntity.badRequest().build();
4 changes: 4 additions & 0 deletions src/main/java/roomescape/reservation/ReservationRequest.java
Original file line number Diff line number Diff line change
@@ -21,4 +21,8 @@ public Long getTheme() {
public Long getTime() {
return time;
}

public void setName(String name) {
this.name = name;
}
}
3 changes: 3 additions & 0 deletions src/main/java/roomescape/reservation/ReservationResponse.java
Original file line number Diff line number Diff line change
@@ -15,6 +15,9 @@ public ReservationResponse(Long id, String name, String theme, String date, Stri
this.time = time;
}

public ReservationResponse() {
}

public Long getId() {
return id;
}
1 change: 0 additions & 1 deletion src/main/resources/application.properties
Original file line number Diff line number Diff line change
@@ -9,4 +9,3 @@ spring.datasource.url=jdbc:h2:mem:database
#spring.jpa.defer-datasource-initialization=true

#roomescape.auth.jwt.secret= Yn2kjibddFAWtnPJ2AFlL8WXmohJMCvigQggaEypa5E=

16 changes: 16 additions & 0 deletions src/test/java/roomescape/MissionStepTest.java
Original file line number Diff line number Diff line change
@@ -37,6 +37,22 @@ public class MissionStepTest {
assertThat(token).isNotBlank();
}

private String createToken(String email, String password) {
Map<String, String> params = new HashMap<>();
params.put("email", email);
params.put("password", password);

ExtractableResponse<Response> response = RestAssured.given().log().all()
.contentType(ContentType.JSON)
.body(params)
.when().post("/login")
.then().log().all()
.statusCode(200)
.extract();

return response.headers().get("Set-Cookie").getValue().split(";")[0].split("=")[1];
}

@Test
void 이단계() {
String token = createToken("admin@email.com", "password"); // 일단계에서 토큰을 추출하는 로직을 메서드로 따로 만들어서 활용하세요.