Skip to content

Commit

Permalink
feat: 멤버의 최신 기수를 조회하여 가져오도록 수정 (#464)
Browse files Browse the repository at this point in the history
  • Loading branch information
hocaron authored Dec 26, 2024
2 parents 25c0789 + 1fe98d1 commit 5922f3f
Show file tree
Hide file tree
Showing 8 changed files with 62 additions and 50 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -9,4 +9,6 @@ public interface MemberGenerationRepositoryCustom {
Optional<MemberGeneration> findByMemberIdAndGenerationNumber(Long memberId, Integer generationNumber);

List<MemberGeneration> findByMemberIdsAndGenerationNumber(List<Long> memberIds, Integer generationNumber);
}

Optional<MemberGeneration> findLatestByMemberId(Long memberId);
}
Original file line number Diff line number Diff line change
Expand Up @@ -35,4 +35,16 @@ public List<MemberGeneration> findByMemberIdsAndGenerationNumber(List<Long> memb
.where(member.id.in(memberIds), generation.number.eq(generationNumber))
.fetch();
}

public Optional<MemberGeneration> findLatestByMemberId(Long memberId) {
return Optional.ofNullable(queryFactory
.selectFrom(memberGeneration)
.join(memberGeneration.member, member)
.join(memberGeneration.generation, generation)
.where(member.id.eq(memberId))
.orderBy(generation.number.desc())
.limit(1)
.fetchFirst()
);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
import kr.mashup.branding.domain.ResultCode;
import kr.mashup.branding.domain.exception.BadRequestException;
import kr.mashup.branding.domain.exception.GenerationIntegrityFailException;
import kr.mashup.branding.domain.exception.NotFoundException;
import kr.mashup.branding.domain.generation.Generation;
import kr.mashup.branding.domain.member.Member;
import kr.mashup.branding.domain.member.MemberGeneration;
Expand Down Expand Up @@ -340,7 +341,12 @@ public void dropOut(final Generation generation, final List<Member> members) {
.forEach(MemberGeneration::dropOut);
}

public MemberGeneration getCurrentMemberGeneration(Member member) {
public MemberGeneration getLatestMemberGeneration(long memberId) {
return memberGenerationRepository.findLatestByMemberId(memberId)
.orElseThrow(NotFoundException::new);
}

public MemberGeneration getLatestMemberGeneration(Member member) {
return member.getMemberGenerations()
.stream()
.max(Comparator.comparingInt(mg -> mg.getGeneration().getNumber()))
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,12 @@
import kr.mashup.branding.domain.exception.UnauthorizedException;
import kr.mashup.branding.security.JwtService;
import kr.mashup.branding.security.MemberAuth;
import kr.mashup.branding.service.member.MemberService;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.slf4j.MDC;
import org.springframework.core.MethodParameter;
import org.springframework.http.HttpHeaders;
import org.springframework.stereotype.Component;
import org.springframework.web.bind.support.WebDataBinderFactory;
import org.springframework.web.context.request.NativeWebRequest;
Expand All @@ -21,6 +23,7 @@
public class MemberAuthArgumentResolver implements HandlerMethodArgumentResolver {

private final JwtService jwtService;
private final MemberService memberService;
public static final String MDC_MEMBER_ID = "memberId";

@Override
Expand All @@ -30,20 +33,33 @@ public boolean supportsParameter(MethodParameter parameter) {

@Override
public Object resolveArgument(MethodParameter parameter, ModelAndViewContainer mavContainer, NativeWebRequest webRequest, WebDataBinderFactory binderFactory) throws Exception {
String authorization = webRequest.getHeader("Authorization");
//Assert.notNull(authorization, "Authorization Header must be not null");
String token = extractTokenFromHeader(webRequest);
Map<String, Long> decodedToken = jwtService.decode(token);

Long memberId = getMemberId(decodedToken);
Long memberGenerationId = getMemberGenerationId(memberId);

MDC.put(MDC_MEMBER_ID, String.valueOf(memberId));
return MemberAuth.of(memberId, memberGenerationId);
}

private String extractTokenFromHeader(NativeWebRequest webRequest) {
String authorization = webRequest.getHeader(HttpHeaders.AUTHORIZATION);
if (authorization == null || !authorization.startsWith("Bearer ")) {
throw new UnauthorizedException();
}
String token = authorization.substring(7);
Map<String, Long> decodedToken = jwtService.decode(token);
return authorization.substring(7);
}

private Long getMemberId(Map<String, Long> decodedToken) {
Long memberId = decodedToken.get(JwtService.CLAIM_NAME_MEMBER_ID);
Long memberGenerationId = decodedToken.get(JwtService.CLAIM_NAME_MEMBER_GENERATION_ID);
if (memberId == null || memberGenerationId == null) {
if (memberId == null) {
throw new UnauthorizedException();
}
return memberId;
}

MDC.put(MDC_MEMBER_ID, String.valueOf(memberId));
return MemberAuth.of(memberId, memberGenerationId);
private Long getMemberGenerationId(long memberId) {
return memberService.getLatestMemberGeneration(memberId).getId();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,7 @@ public BirthdayCardImageResponse generatePresignedUrl(long memberId) {
@Transactional
public void send(Long memberId, BirthdayCardRequest request) {
Member senderMember = memberService.findMemberById(memberId);
MemberGeneration latestMemberGeneration = memberService.getCurrentMemberGeneration(senderMember);
MemberGeneration latestMemberGeneration = memberService.getLatestMemberGeneration(senderMember);

birthdayCardService.checkAlreadySent(request.getRecipientMemberId(), senderMember, latestMemberGeneration);
birthdayCardService.send(request.getRecipientMemberId(), senderMember, latestMemberGeneration, request.getMessage(), request.getImageUrl());
Expand All @@ -62,7 +62,7 @@ public void send(Long memberId, BirthdayCardRequest request) {
@Transactional(readOnly = true)
public BirthdayCardsResponse getMy(Long memberId) {
Member member = memberService.findMemberById(memberId);
MemberGeneration generation = memberService.getCurrentMemberGeneration(member);
MemberGeneration generation = memberService.getLatestMemberGeneration(member);

List<BirthdayCardResponse> birthdayCards = birthdayCardService.getMy(member, generation)
.stream()
Expand Down
Original file line number Diff line number Diff line change
@@ -1,12 +1,5 @@
package kr.mashup.branding.facade.member;

import java.time.LocalDateTime;
import java.util.Comparator;
import java.util.List;

import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import kr.mashup.branding.domain.exception.GenerationIntegrityFailException;
import kr.mashup.branding.domain.generation.Generation;
import kr.mashup.branding.domain.invite.Invite;
Expand All @@ -16,24 +9,19 @@
import kr.mashup.branding.domain.member.exception.MemberInvalidInviteCodeException;
import kr.mashup.branding.domain.scorehistory.ScoreHistory;
import kr.mashup.branding.domain.scorehistory.ScoreType;
import kr.mashup.branding.service.member.MemberCreateDto;
import kr.mashup.branding.security.JwtService;
import kr.mashup.branding.service.invite.InviteService;
import kr.mashup.branding.service.member.MemberCreateDto;
import kr.mashup.branding.service.member.MemberService;
import kr.mashup.branding.service.scorehistory.ScoreHistoryService;
import kr.mashup.branding.ui.member.request.LoginRequest;
import kr.mashup.branding.ui.member.request.MemberGenerationRequest;
import kr.mashup.branding.ui.member.request.MemberPasswordChangeRequest;
import kr.mashup.branding.ui.member.request.PushNotificationRequest;
import kr.mashup.branding.ui.member.request.SignUpRequest;
import kr.mashup.branding.ui.member.request.ValidInviteRequest;
import kr.mashup.branding.ui.member.response.AccessResponse;
import kr.mashup.branding.ui.member.response.ExistsResponse;
import kr.mashup.branding.ui.member.response.MemberGenerationsResponse;
import kr.mashup.branding.ui.member.response.MemberInfoResponse;
import kr.mashup.branding.ui.member.response.TokenResponse;
import kr.mashup.branding.ui.member.response.ValidResponse;
import kr.mashup.branding.ui.member.request.*;
import kr.mashup.branding.ui.member.response.*;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.time.LocalDateTime;
import java.util.List;


@Service
Expand Down Expand Up @@ -121,8 +109,8 @@ public void withdraw(Long memberId) {
memberService.deleteMember(memberId);
}

public TokenResponse getAccessToken(Long memberId, Long memberGenerationId) {
final String token = jwtService.encode(memberId, memberGenerationId);
public TokenResponse getAccessToken(Long memberId) {
final String token = jwtService.encode(memberId);
return TokenResponse.of(token);
}

Expand Down Expand Up @@ -175,15 +163,8 @@ public void changePassword(
memberService.resetPassword(identification, request.getNewPassword());
}

private MemberGeneration getLatestMemberGeneration(Member member) {
return member.getMemberGenerations().stream().max(Comparator.comparing(
memberGeneration -> memberGeneration.getGeneration().getNumber()
)).orElseThrow(GenerationIntegrityFailException::new);
}

private String getToken(Member member) {
final MemberGeneration latestMemberGeneration = getLatestMemberGeneration(member);
return jwtService.encode(member.getId(), latestMemberGeneration.getId());
return jwtService.encode(member.getId());
}

private void checkMemberGenerationIsIn(Long memberGenerationId, List<MemberGeneration> memberGenerations) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,31 +22,26 @@ public class JwtService {
private String secretKey;

public static final String CLAIM_NAME_MEMBER_ID = "MemberId";
public static final String CLAIM_NAME_MEMBER_GENERATION_ID = "MemberGenerationId";

private Algorithm algorithm;
private JWTVerifier jwtVerifier;

public String encode(Long memberId, Long memberGenerationId) {
public String encode(Long memberId) {

LocalDateTime expiredAt = LocalDateTime.now().plusWeeks(4L);

Date date = java.sql.Timestamp.valueOf(expiredAt);

return JWT.create()
.withClaim(CLAIM_NAME_MEMBER_ID, memberId)
.withClaim(CLAIM_NAME_MEMBER_GENERATION_ID, memberGenerationId)
.withExpiresAt(date)
.sign(algorithm);
}

public Map<String, Long> decode(String token) {
try {
DecodedJWT jwt = jwtVerifier.verify(token);
return Map.of(
CLAIM_NAME_MEMBER_ID, jwt.getClaim(CLAIM_NAME_MEMBER_ID).asLong(),
CLAIM_NAME_MEMBER_GENERATION_ID, jwt.getClaim(CLAIM_NAME_MEMBER_GENERATION_ID).asLong()
);
return Map.of(CLAIM_NAME_MEMBER_ID, jwt.getClaim(CLAIM_NAME_MEMBER_ID).asLong());
} catch (JWTVerificationException e) {
log.warn("Failed to decode jwt. token: {}", token, e);
throw new UnauthorizedException();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -104,7 +104,7 @@ public ApiResponse<TokenResponse> issueAccessToken(
@ApiIgnore MemberAuth memberAuth
) {
final TokenResponse tokenResponse
= memberFacadeService.getAccessToken(memberAuth.getMemberId(), memberAuth.getMemberGenerationId());
= memberFacadeService.getAccessToken(memberAuth.getMemberId());

return ApiResponse.success(tokenResponse);
}
Expand Down

0 comments on commit 5922f3f

Please sign in to comment.