3. 토큰 API 구현

이용준·2023년 9월 30일
0

JWT

목록 보기
3/4

1. 개발자 되기

1) service

  • UserService

    @RequiredConstructor
    @Service
    public class UserService{
      ...
      public User findById(Long userId){
        return userRepository.findById(userId)
          .orElseThrow(() -> new IllegalArgumentException("Unexpected user"));
      }
    }

    유저 ID로 유저 검색해 전달하는 메서드 추가

    • RefreshTokenService
      @RequiredConstructor
      @Service
      public class RefreshTokenService{
        private final RefreshTokenRepository refreshTokenRepository
        
        public RefreshToken findByRefreshToken(String refreshToken){
          return refreshTokenRepoitory.findByRefreshToken(refreshToken)
            .orElseThrow(() -> new IllegalArgumentException("Unexpected Token"));
        }
      }

      리프레시 토큰 객체 검색해 전달하는 메서드 구현

    • TokenService
      @RequiredConstructor
      @Service
      public class TokenService{
        private final TokenProvider tokenProvider;
        private final RefreshTokenService refreshTokenService;
        private final UserService userService;
        
        public String createNewAccessToken(String refreshToken){
          if(!tokenProvider.validToken(refreshToken)){
            throw new IllegalArgumentException("Unexpected token");
          }
          
          Long userId = refreshtoken.findByRefreshToken(refreshToken).getUserId();
          User user = userService.findById(userId);
          
          return tokenProvider.generationToken(user, Duration.ofHours(2));
        }
      }
      1. createNewAccessToken : 리프레시 토큰으로 유효성 검사 진행
      2. 사용자 ID 찾음
      3. generateToken 새로운 액세스 토큰 생성

2) dto (요청 및 응답)

  • CreateAccessTokenRequest (토큰 생성 요청)
@Getter
@Setter
public class CreateAccessTokenRequest{
  private String refreshToken;
}
  • CreateAccessTokenResponse (토큰 생성 응답)
@Getter
@Setter
public class CreateAccessTokenResposne{
  private String accessToken;
}

3) Controller

  • 실제 요청 받고 처리할 컨트롤러 생성
  • TokenApiController
@RequiredConstructor
@RestController
public class TokenApiController{
  private final TokenService tokenService;
  
  @PostMapping("/api/token")
  public ResponseEntity<CreateAccessTokenResponse> createNewAccessToken(@RequestBody CreateTokenRequest request){
    String newAccessToken = tokenService.createNewAccessToken(request.getRefreshToken());
    
    return ResponseEntity.status(HttpStatus.CREATED)
      .body(new CreateAccessTokenResponse(newAccessToken));
  }
}

토큰 서비스에서 리프레시 토큰 기반으로 새로운 액세스 토큰 생성

2. 코드로 배우는 스프링부트

SecurityConfig

  • ApiCheckFilter 적용
  • ApiLoginFilter 적용
@Configuration
@Log4j2
@EnableMethodSecurity(prePostEnabled = true)
public class SecurityConfig{
  @Autowired
  private ClubUserDetailService userDetails;
  
  ...
  
  @Bean
  public SecurityFilterChain filterChain(final HttpSecurity http) throws Exception{
  log.info(" ================== filterChain Execute===============");
  ...
  
  /* ApiCheckFilter */
  // add Filter
  http.addFilterBefore(apiCheckFilter(), UsernamePasswordAuthenticationFilter.class);
  
  // AuthenticationManager 설정 (Authentication 인증)
  AuthenticationManagerBuilder authenticationManagerBuilder = http.getSharedObject(AuthenticationManagerBuilder.class);
  
  // Get AuthenticationManager
  AuthenticationManager authenticationManager = authenticationManagerBuilder.build();
  
  http.authenticationManager(authenticationManager);
  
  /* ApiLoginFilter */
  ApiLoginFilter apiLoginFilter = new ApiLoginFilter("/api/login", jwtUtil());
  apiLoginFilter.setAuthenticationManager(authenticationManager);
  
  http.addFilterBefore(apiLoginFilter, UsernamePasswordAuthenticationFilter.class);
  
  return http.build();
  }
  
  ...
  
  // 토큰 검사 필터
  @Bean
  public ApiCheckFilter apiCheckFilter(){
    return new ApiCheckFilter("/notes/**/*", jwtUtil());
  }
  
}
profile
뚝딱뚝딱

0개의 댓글