Skip to content

Commit

Permalink
[Feat] ArgumentResolver 구현 및 멤버 조회, 등록 적용(#13)
Browse files Browse the repository at this point in the history
  • Loading branch information
sjk4618 committed May 28, 2024
1 parent 1b7f8a0 commit 58c6864
Show file tree
Hide file tree
Showing 12 changed files with 97 additions and 26 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,9 @@
@Getter
public enum SuccessMessage {

MEMBER_CREATE_SUCCESS(HttpStatus.CREATED.value(), "유저 생성이 완료되었습니다."),
MEMBER_CREATE_SUCCESS(HttpStatus.CREATED.value(), "유저 생성에 성공했습니다."),
MEMBER_FIND_SUCCESS(HttpStatus.OK.value(), "유저 검색에 성공했습니다."),


BLOG_CREATE_SUCCESS(HttpStatus.CREATED.value(), "블로그 생성이 완료되었습니다."),
BLOG_CONTENT_CREATE_SUCCESS(HttpStatus.CREATED.value(), "블로그에 글 작성이 완료되었습니다."),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,9 +8,10 @@
import org.springframework.beans.factory.annotation.Value;
import org.springframework.security.core.Authentication;
import org.springframework.stereotype.Component;
import org.springframework.stereotype.Service;

@RequiredArgsConstructor
@Component
@Service
public class JwtTokenProvider {

private final JwtTokenGenerator jwtTokenGenerator;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,11 @@
import org.sopt.springFirstSeminar.common.dto.ErrorMessage;
import org.sopt.springFirstSeminar.exception.UnauthorizedException;
import org.springframework.stereotype.Component;
import org.springframework.stereotype.Service;


@RequiredArgsConstructor
@Component
@Service
public class JwtTokenValidator {

private final JwtTokenGenerator jwtTokenGenerator;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,5 +7,5 @@

@Target(ElementType.PARAMETER)
@Retention(RetentionPolicy.RUNTIME)
public @interface UserId {
public @interface MemberId {
}
Original file line number Diff line number Diff line change
Expand Up @@ -21,9 +21,9 @@ public class RefreshToken {
@Indexed
private String refreshToken;

public static RefreshToken of(final Long userId, final String refreshToken) {
public static RefreshToken of(final Long memberId, final String refreshToken) {
return RefreshToken.builder()
.id(userId)
.id(memberId)
.refreshToken(refreshToken)
.build();
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,9 +1,10 @@
package org.sopt.springFirstSeminar.common.jwt.auth.filter;
package org.sopt.springFirstSeminar.common.jwt.auth;

import lombok.RequiredArgsConstructor;
import org.sopt.springFirstSeminar.common.jwt.JwtTokenProvider;
import org.sopt.springFirstSeminar.common.jwt.JwtTokenValidator;
import org.sopt.springFirstSeminar.common.jwt.auth.CustomAccessDeniedHandler;
import org.sopt.springFirstSeminar.common.jwt.auth.filter.CustomJwtAuthenticationEntryPoint;
import org.sopt.springFirstSeminar.common.jwt.auth.filter.JwtAuthenticationFilter;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
Expand All @@ -25,7 +26,7 @@ public class SecurityConfig {
private final JwtTokenValidator jwtTokenValidator;


private static final String[] AUTH_WHITE_LIST = {"/api/v1/member"};
private static final String[] AUTH_WHITE_LIST = {"/api/v1/member", "/test"};

@Bean
SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,20 +2,29 @@

import org.springframework.core.MethodParameter;
import org.springframework.security.core.context.SecurityContextHolder;
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;

@Component
public class UserIdArgumentResolver implements HandlerMethodArgumentResolver {

//
@Override
public boolean supportsParameter(MethodParameter parameter) {
boolean hasUserIdAnnotation = parameter.hasParameterAnnotation(UserId.class);

//요청받은 메소드의 파라미터에 @UserId 어노테이션이 붙어있는지 확인
boolean hasUserIdAnnotation = parameter.hasParameterAnnotation(MemberId.class);

//타입이 같은지 확인
boolean isLongType = Long.class.isAssignableFrom(parameter.getParameterType());

//둘 다 true면 아래 resolveArgument 메서드 실행
return hasUserIdAnnotation && isLongType;
}

//SecurityContextHolder에 있는 UserId 추출
@Override
public Object resolveArgument(MethodParameter parameter, ModelAndViewContainer mavContainer, NativeWebRequest webRequest, WebDataBinderFactory binderFactory) throws Exception {
return SecurityContextHolder.getContext()
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
package org.sopt.springFirstSeminar.common.jwt.auth;


import lombok.RequiredArgsConstructor;
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;

@RequiredArgsConstructor
@Configuration
public class WebConfig implements WebMvcConfigurer {
private final UserIdArgumentResolver userIdArgumentResolver;

@Override
public void addArgumentResolvers(List<HandlerMethodArgumentResolver> resolvers) {
resolvers.add(userIdArgumentResolver);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.sopt.springFirstSeminar.common.Constant;
import org.sopt.springFirstSeminar.common.dto.ErrorMessage;
import org.sopt.springFirstSeminar.common.jwt.JwtTokenProvider;
Expand All @@ -25,6 +26,7 @@

@RequiredArgsConstructor
@Component
@Slf4j
public class JwtAuthenticationFilter extends OncePerRequestFilter {

private final JwtTokenProvider jwtTokenProvider;
Expand All @@ -33,9 +35,13 @@ public class JwtAuthenticationFilter extends OncePerRequestFilter {

@Override
protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain) throws ServletException, IOException {
final String accessToken = getAccessToken(request);
jwtTokenValidator.validateAccessToken(accessToken);
doAuthentication(request, jwtTokenProvider.getSubject(accessToken));
try {
final String accessToken = getAccessToken(request);
jwtTokenValidator.validateAccessToken(accessToken);
doAuthentication(request, jwtTokenProvider.getSubject(accessToken));
} catch(UnauthorizedException e){
log.info("———");
}
filterChain.doFilter(request, response);
}

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
package org.sopt.springFirstSeminar.common.jwt.auth.redis.repository;

import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.redis.connection.RedisConnectionFactory;
import org.springframework.data.redis.connection.lettuce.LettuceConnectionFactory;

@Configuration
public class RedisConfig {

@Value("${spring.data.redis.host}")
private String host;

@Value("${spring.data.redis.port}")
private int port;

@Bean
public RedisConnectionFactory redisConnectionFactory() {
return new LettuceConnectionFactory(host, port);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
import org.sopt.springFirstSeminar.common.BaseResponse;
import org.sopt.springFirstSeminar.common.Constant;
import org.sopt.springFirstSeminar.common.dto.SuccessMessage;
import org.sopt.springFirstSeminar.common.jwt.auth.MemberId;
import org.sopt.springFirstSeminar.common.jwt.dto.TokenResponse;
import org.sopt.springFirstSeminar.service.MemberService;
import org.sopt.springFirstSeminar.service.dto.MemberCreateDTO;
Expand All @@ -26,17 +27,19 @@ public class MemberController {
private final MemberService memberService;

@PostMapping
public ResponseEntity<BaseResponse<?>> postMember(@RequestHeader(Constant.AUTHORIZATION) final String token,
@RequestBody MemberCreateDTO memberCreate)
public ResponseEntity<BaseResponse<?>> postMember(@RequestBody MemberCreateDTO memberCreate)
{
final TokenResponse userJoinResponse = memberService.createMember(token, memberCreate);
final TokenResponse memberJoinResponse = memberService.createMember(memberCreate);

return ApiResponseUtil.success(SuccessMessage.MEMBER_CREATE_SUCCESS, userJoinResponse);
return ApiResponseUtil.success(SuccessMessage.MEMBER_CREATE_SUCCESS, memberJoinResponse);
}

@GetMapping("/{memberId}")
public ResponseEntity<MemberFindDTO> findMemberById(@PathVariable final Long memberId) {
return ResponseEntity.ok(memberService.findMemberById(memberId));
@GetMapping
public ResponseEntity<BaseResponse<?>> findMemberById(@MemberId final Long memberId) {

final MemberFindDTO memberFindDTO = memberService.findMemberById(memberId);

return ApiResponseUtil.success(SuccessMessage.MEMBER_FIND_SUCCESS, memberFindDTO);
}

@DeleteMapping("/{memberId}")
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,28 +23,34 @@

@Service
@RequiredArgsConstructor
@Transactional(readOnly = true)
public class MemberService {

private final MemberRepository memberRepository;

private final JwtTokenProvider jwtTokenProvider;
private final RefreshTokenRepository refreshTokenRepository;

//멤버가입
@Transactional
public TokenResponse createMember(String token, MemberCreateDTO memberCreate) {
public TokenResponse createMember(MemberCreateDTO memberCreate) {

Member createdMember = memberRepository.save(
Member.create(memberCreate.name(), memberCreate.part(), memberCreate.age())
);

Long createdMemberId = createdMember.getId();
Token issuedToken = jwtTokenProvider.issueTokens(createdMemberId);
updateRefreshToken(issuedToken.refreshToken(), createdMember);
updateRefreshToken(issuedToken.refreshToken(), createdMemberId);

return TokenResponse.of(issuedToken.accessToken(), issuedToken.refreshToken(), createdMemberId);
}

private void updateRefreshToken(String refreshToken, Member member) {
refreshTokenRepository.save(RefreshToken.of(member.getId(), refreshToken));




private void updateRefreshToken(String refreshToken, Long memberId) {
refreshTokenRepository.save(RefreshToken.of(memberId, refreshToken));
}

public void findById(final Long memberId) {
Expand Down

0 comments on commit 58c6864

Please sign in to comment.