-
Notifications
You must be signed in to change notification settings - Fork 56
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 MVC] 한상우 미션 제출합니다. #29
base: sangu1026
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,39 @@ | ||
package roomescape; | ||
|
||
import io.jsonwebtoken.Jwts; | ||
import io.jsonwebtoken.security.Keys; | ||
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.infrastructure.JwtTokenDecoder; | ||
import roomescape.infrastructure.TokenExtractor; | ||
import roomescape.member.Member; | ||
import roomescape.member.MemberService; | ||
|
||
@Component | ||
public class AdminHandlerInterceptor implements HandlerInterceptor { | ||
private MemberService memberService; | ||
|
||
public AdminHandlerInterceptor(MemberService memberService) { | ||
this.memberService = memberService; | ||
} | ||
|
||
@Override | ||
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception { | ||
|
||
String token = TokenExtractor.extractTokenFromCookie(request.getCookies()); | ||
Long id = JwtTokenDecoder.decodeToken(token); | ||
Member member = memberService.findById(id); | ||
|
||
if (member == null || !member.getRole().equals("ADMIN")) { | ||
response.setStatus(401); | ||
return false; | ||
} | ||
|
||
return true; | ||
} | ||
|
||
|
||
} |
Original file line number | Diff line number | Diff line change | ||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|
@@ -0,0 +1,47 @@ | ||||||||||||
package roomescape; | ||||||||||||
|
||||||||||||
import io.jsonwebtoken.Jwts; | ||||||||||||
import io.jsonwebtoken.security.Keys; | ||||||||||||
import jakarta.servlet.http.Cookie; | ||||||||||||
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.infrastructure.JwtTokenDecoder; | ||||||||||||
import roomescape.infrastructure.TokenExtractor; | ||||||||||||
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); | ||||||||||||
// return Member.class.isAssignableFrom(parameter.getParameterType()); | ||||||||||||
} | ||||||||||||
|
||||||||||||
@Override | ||||||||||||
public Object resolveArgument(MethodParameter parameter, ModelAndViewContainer mavContainer, NativeWebRequest webRequest, WebDataBinderFactory binderFactory) throws Exception { | ||||||||||||
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.
Suggested change
받는 파라미터의 길이가 길고 개수가 4개나 되니 이렇게 수정하면 가독성이 더 좋지 않을까요?? |
||||||||||||
HttpServletRequest request = webRequest.getNativeRequest(HttpServletRequest.class); | ||||||||||||
Cookie[] cookies = request.getCookies(); | ||||||||||||
String token = TokenExtractor.extractTokenFromCookie(cookies); | ||||||||||||
if (token == null) return null; | ||||||||||||
|
||||||||||||
Long id = JwtTokenDecoder.decodeToken(token); | ||||||||||||
Member member = memberService.findById(id); | ||||||||||||
return new LoginMember(member.getId(), member.getName(), member.getEmail(), member.getPassword()); | ||||||||||||
} | ||||||||||||
|
||||||||||||
|
||||||||||||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,33 @@ | ||
package roomescape.config; | ||
|
||
import org.springframework.context.annotation.Configuration; | ||
import org.springframework.web.method.support.HandlerMethodArgumentResolver; | ||
import org.springframework.web.servlet.config.annotation.InterceptorRegistry; | ||
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer; | ||
import roomescape.AdminHandlerInterceptor; | ||
import roomescape.LoginMemberArgumentResolver; | ||
|
||
import java.util.List; | ||
|
||
@Configuration | ||
public class WebConfig implements WebMvcConfigurer { | ||
private final LoginMemberArgumentResolver loginMemberArgumentResolver; | ||
private final AdminHandlerInterceptor adminHandlerInterceptor; | ||
|
||
|
||
public WebConfig(LoginMemberArgumentResolver loginMemberArgumentResolver, AdminHandlerInterceptor adminHandlerInterceptor) { | ||
this.loginMemberArgumentResolver = loginMemberArgumentResolver; | ||
this.adminHandlerInterceptor = adminHandlerInterceptor; | ||
} | ||
|
||
@Override | ||
public void addArgumentResolvers(List<HandlerMethodArgumentResolver> resolvers) { | ||
resolvers.add(loginMemberArgumentResolver); | ||
} | ||
|
||
@Override | ||
public void addInterceptors(InterceptorRegistry registry) { | ||
registry.addInterceptor(adminHandlerInterceptor) | ||
.addPathPatterns("/admin"); | ||
Comment on lines
+30
to
+31
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. 저는 |
||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,15 @@ | ||
package roomescape.infrastructure; | ||
|
||
import io.jsonwebtoken.Jwts; | ||
import io.jsonwebtoken.security.Keys; | ||
|
||
public class JwtTokenDecoder { | ||
public static Long decodeToken(String token) { | ||
Long memberId = Long.valueOf(Jwts.parserBuilder() | ||
.setSigningKey(Keys.hmacShaKeyFor("Yn2kjibddFAWtnPJ2AFlL8WXmohJMCvigQggaEypa5E=".getBytes())) | ||
.build() | ||
.parseClaimsJws(token) | ||
.getBody().getSubject()); | ||
return memberId; | ||
} | ||
} |
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.
혹시 Util 이라는 단어에 대해서 아실까요?? 하나로 구현하는건 어떨지 한번 같이 이야기 해보고 싶어서 리뷰 남깁니다! |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,24 @@ | ||
package roomescape.infrastructure; | ||
|
||
|
||
import io.jsonwebtoken.Jwts; | ||
import io.jsonwebtoken.security.Keys; | ||
import org.springframework.beans.factory.annotation.Value; | ||
import org.springframework.stereotype.Component; | ||
import roomescape.member.Member; | ||
|
||
@Component | ||
public class JwtTokenProvider { | ||
@Value("Yn2kjibddFAWtnPJ2AFlL8WXmohJMCvigQggaEypa5E=") | ||
private String secretKey; | ||
|
||
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(); | ||
} | ||
|
||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,15 @@ | ||
package roomescape.infrastructure; | ||
|
||
import jakarta.servlet.http.Cookie; | ||
|
||
public class TokenExtractor { | ||
|
||
public static String extractTokenFromCookie(Cookie[] cookies) { | ||
for (Cookie cookie : cookies) { | ||
if (cookie.getName().equals("token")) { | ||
return cookie.getValue(); | ||
} | ||
} | ||
return ""; | ||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,30 @@ | ||
package roomescape.member; | ||
public class LoginMember{ | ||
private Long id; | ||
private String name; | ||
private String email; | ||
private String password; | ||
|
||
public LoginMember(Long id, String name, String email, String password) { | ||
this.id = id; | ||
this.name = name; | ||
this.email = email; | ||
this.password = password; | ||
} | ||
|
||
public Long getId() { | ||
return id; | ||
} | ||
|
||
public String getName() { | ||
return name; | ||
} | ||
|
||
public String getEmail() { | ||
return email; | ||
} | ||
|
||
public String getPassword() { | ||
return password; | ||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,22 @@ | ||
package roomescape.member; | ||
|
||
import lombok.Getter; | ||
|
||
|
||
public class LoginRequest { | ||
private String email; | ||
private String password; | ||
|
||
public LoginRequest(String email, String password) { | ||
this.email = email; | ||
this.password = password; | ||
} | ||
|
||
public String getEmail() { | ||
return email; | ||
} | ||
|
||
public String getPassword() { | ||
return password; | ||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,13 @@ | ||
package roomescape.member; | ||
|
||
public class LoginResponse { | ||
private String name; | ||
|
||
public LoginResponse(String name) { | ||
this.name = name; | ||
} | ||
|
||
public String getName() { | ||
return name; | ||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,17 +1,42 @@ | ||
package roomescape.member; | ||
|
||
import io.jsonwebtoken.Jwts; | ||
import io.jsonwebtoken.security.Keys; | ||
import org.springframework.stereotype.Service; | ||
import roomescape.infrastructure.JwtTokenDecoder; | ||
import roomescape.infrastructure.JwtTokenProvider; | ||
|
||
@Service | ||
public class MemberService { | ||
private MemberDao memberDao; | ||
private JwtTokenProvider jwtTokenProvider; | ||
|
||
public MemberService(MemberDao memberDao) { | ||
public MemberService(MemberDao memberDao,JwtTokenProvider jwtTokenProvider) { | ||
this.memberDao = memberDao; | ||
this.jwtTokenProvider = jwtTokenProvider; | ||
} | ||
Comment on lines
11
to
17
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.
저도 해당 어노테이션을 사용해보면 좋을것 같다는 리뷰를 받아서 말씀드려요😊 |
||
|
||
public MemberResponse createMember(MemberRequest memberRequest) { | ||
Member member = memberDao.save(new Member(memberRequest.getName(), memberRequest.getEmail(), memberRequest.getPassword(), "USER")); | ||
return new MemberResponse(member.getId(), member.getName(), member.getEmail()); | ||
} | ||
|
||
public String login(LoginRequest loginRequest){ | ||
Member member = memberDao.findByEmailAndPassword(loginRequest.getEmail(),loginRequest.getPassword()); | ||
|
||
String accessToken = jwtTokenProvider.createToken(member); | ||
|
||
return accessToken; | ||
} | ||
|
||
public LoginResponse checkLogin (String token) { | ||
|
||
Long memberId = JwtTokenDecoder.decodeToken(token); | ||
Member member = memberDao.findById(memberId); | ||
|
||
return new LoginResponse(member.getName()); | ||
} | ||
public Member findById(Long id) { | ||
return memberDao.findById(id); | ||
} | ||
} |
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.
member가 존재하지 않는 것에 대해서도 같은 에러처리를 하셨네요! 혹시 이유가 따로 있을까요??