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

#6 - 6차 세미나 실습 과제 제출 #6

Open
wants to merge 4 commits into
base: main
Choose a base branch
from
Open

#6 - 6차 세미나 실습 과제 제출 #6

wants to merge 4 commits into from

Conversation

ckkim817
Copy link
Contributor

@ckkim817 ckkim817 commented Jun 2, 2024

📟 관련 이슈

💻 과제 내용

로그인 진행 시 Access Token과 Refresh Token을 함께 반환하는 로직을 구현합니다.

  1. RedisConfig 추가

@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);
}
@Bean
public RedisTemplate<String, Object> redisTemplate(RedisConnectionFactory connectionFactory) {
RedisTemplate<String, Object> template = new RedisTemplate<>();
template.setConnectionFactory(connectionFactory);
template.setKeySerializer(new StringRedisSerializer());
template.setValueSerializer(new GenericJackson2JsonRedisSerializer());
return template;
}
}

  1. 가입 시 Refresh Token을 추가로 반환

public record UserJoinResponse(
String accessToken,
String refreshToken,
String userId
) {
public static UserJoinResponse of(
String accessToken,
String refreshToken,
String userId
) {
return new UserJoinResponse(accessToken, refreshToken, userId);
}
}

@Transactional
public UserJoinResponse createMember(
MemberCreateDTO memberCreateDTO
) {
Member member = memberRepository.save(
Member.create(memberCreateDTO.name(), memberCreateDTO.part(), memberCreateDTO.age())
);
Long memberId = member.getId();
String accessToken = jwtTokenProvider.issueAccessToken(
UserAuthentication.createUserAuthentication(memberId)
);
String refreshToken = jwtTokenProvider.issueRefreshToken(
UserAuthentication.createUserAuthentication(memberId)
);
redisTokenRepository.save(Token.of(memberId, refreshToken));
return UserJoinResponse.of(accessToken, refreshToken, memberId.toString());
}

  1. 결과
image

Refresh Token으로 Access Token을 재발급 받는 로직 구현합니다. (Redis 활용)

  1. DTO 정의

public record AccessTokenDTO(
String accessToken
) {
public static AccessTokenDTO of(String accessToken) {
return new AccessTokenDTO(accessToken);
}
}

  1. TokenService 및 JwtTokenProvider에 새 액세스 토큰하는 메서드 작성

@Service
@RequiredArgsConstructor
public class TokenService {
private final RedisTokenRepository redisTokenRepository;
private final JwtTokenProvider jwtTokenProvider;
@Transactional
public AccessTokenDTO reissueAccessToken(Long userId) {
Token token = redisTokenRepository.findById(userId).orElseThrow(
() -> new UnauthorizedException(ErrorMessage.MEMBER_NOT_FOUND)
);
jwtTokenProvider.validateToken(token.getRefreshToken());
String newAccessToken = jwtTokenProvider.newAccessToken(token.getRefreshToken());
return AccessTokenDTO.of(newAccessToken);
}
}

public String newAccessToken(String refreshToken) {
Claims claims = getBody(refreshToken);
Long userId = Long.valueOf(claims.get(USER_ID).toString());
Authentication authentication = UserAuthentication.createUserAuthentication(userId);
return issueAccessToken(authentication);
}

  1. TokenController 작성

@Transactional
@RestController
@RequiredArgsConstructor
@RequestMapping("/api/v1/token")
public class TokenController {
private final TokenService tokenService;
private final PrincipalHandler principalHandler;
@PostMapping("/reissue")
public ResponseEntity<AccessTokenDTO> reissueAccessToken() {
Long userId = principalHandler.getUserIdFromPrincipal();
AccessTokenDTO newAccessTokenResponse = tokenService.reissueAccessToken(userId);
return ResponseEntity.status(HttpStatus.CREATED)
.body(newAccessTokenResponse);
}
}

  1. 결과
image

🤔 구현 고민 사항

  • 알고 계셨나요? Token 엔티티에 @NoArgsConstructor 어노테이션을 지정해주지 않으면 MappingException이 발생한다는 사실? 저는 2시간 만에 알아냈습니다 ..

@ckkim817 ckkim817 changed the title 6차 세미나 실습 과제 #6 - 6차 세미나 실습 과제 제출 Jun 2, 2024
@ckkim817 ckkim817 self-assigned this Jun 2, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

6차 세미나 실습 과제 - Access Token 재발급 로직 구현하기
1 participant