본문 바로가기

전체 글42

이미지 업로드 기능, S3 전환을 염두에 두고 설계하기 지금 이미지 업로드는 로컬 디스크에 저장하지만, 나중에 AWS 배포할 때는 S3에 저장하도록 바꿀 계획이다. 이때 저장 방식만 바뀌는 거지, 이미지를 업로드하고 게시글에 연결하는 흐름 자체는 바뀌지 않는다. 그래서 애초에 어디에 저장하는가를 다루는 코드와 저장된 결과를 가지고 무엇을 하는가를 다루는 코드를 분리해두었다. 분리구조BoardImageService (비즈니스 로직) ↓ 파일을 "저장해달라"고 요청만 함FileStorageService (저장 방식만 담당) ↓ 실제로 어디에 저장할지는 이 클래스만 앎로컬 디스크 (지금) → 나중에 S3로 교체 BoardImageService는 이렇게만 알고 있음String imageUrl = fileStorageService.store(file); 파.. 2026. 9. 2.
"Request는 Builder, Response는 from() — DTO를 다르게 만드는 이유" 보드 이미지가 잘 올라가는지 테스트를 해보던 중 테스트에러가 났었다.기존코드@NoArgsConstructor@Getterpublic class TokenRefreshRequest { @NotBlank private String refreshToken;} @NoArgsConstructor는 매개변수가 없는 생성자만 만들어준다. String refreshToken을 받는 생성자는 애초에 존재하지 않았던 것.실제 운영 환경에서는 Jackson이 빈 객체를 만든 다음 리플렉션으로 필드에 값을 꽂아 넣으니 문제가 없었지만, 테스트 코드에서는 사람이 직접 생성자를 호출해야 하니 이 문제가 드러난 것이다. 해결@NoArgsConstructor@Getterpublic class TokenRefreshRequest .. 2026. 9. 2.
JWT 인증에서 경로별로 permitAll을 다르게 줘야 하는 이유 로그아웃을 구현하다 로그아웃도 permitAll()을 해줘야 하는지에 대해 고민했다.처음엔 logout이 있는 상황에서도 securityconfig에.authorizeHttpRequests(auth -> auth .requestMatchers("/api/auth/**").permitAll() .anyRequest().authenticated())이렇게 다 허용을 해줬었다. 그런데 이렇게 되어 있으면 /api/auth/logout도 permitAll()에 걸려서 인증 없이도 통과 된다. 그러면 JwtFilter가 토큰을 검증은 하겠지만, permitAll 경로는 인증 실패해도 필터 체인이 막지 않기 때문에 @AuthenticationPrincipal UserDetails userDetails가 .. 2026. 9. 2.
Postman 테스트 중 발견한 세 가지 오류 - CORS 설정 & JwtFilter 예외 처리 & DTO 역직렬화 실패 로그인, 회원가입 기능을 완료한 후 Postman으로 테스트를 하던 중 다음과 같은 3가지 문제점이 있었다.문제 1. SecurityConfig - Postman에서 CORS 차단리액트로 연결해 로그인을 테스트 했을 때는 로그인이 잘 되었지만 포스트맨으로 테스트 시 403 오류가 남오류가 난 이유CORS는 브라우저가 다른 출처(Origin)로 요청을 보낼 때 서버가 허용했는지 확인하는 보안 정책임 원래 코드에서 http://localhost:5173만 허용했는데, Postman은 브라우저가 아니라서 Origin 헤더를 http://localhost:5173으로 보내지 않는다. 서버 입장에서는 허용되지 않은 출처에서 온 요청이라 차단한 것이다.바꿔야 하는 이유개발 중에는 Postman, 다른 포트, 다른.. 2026. 6. 24.
Spring Boot + Redis로 Refresh Token 구현하기 Access Token 이란로그인을 하면 서버가 사용자에게 "당신이 누구인지 증명하는 표" 를 발급해준다. 이게 바로 Access Token이다.클라이언트는 이 토큰을 들고 다니면서 API를 호출할 때마다 헤더에 담아 보낸다. 서버는 매번 DB를 조회하는 대신, 토큰의 서명만 검증해서 "이 사람 맞네" 하고 통과시켜준다. 이 방식의 장점은 서버가 DB를 안 봐도 된다는 점이다. 토큰 자체에 사용자 정보가 담겨 있고, 서명만 맞으면 유효하다고 판단하기 때문에 빠르고 가볍다. 단 토큰이 탈취 당하면 서버는 서명만 보기 때문에, 훔친 토큰이라도 서명이 맞으면 그냥 통과시켜버린다. 중간에 취소할 수도 없어서 토큰이 만료될 때까지 공격자가 마음대로 쓸 수 있다.그래서 Access Token은 만료 시간을 짧게 설.. 2026. 6. 16.
Spring Boot JWT 인증 구현하기 - 로그인, 회원가입 API AuthService가 필요한 이유AuthService는 회원가입과 로그인 비즈니스 로직을 처리하는 곳이다.JWT 인증 구현을 하다 보면 JwtProvider, JwtFilter, SecurityConfig 같은 클래스들을 만들게 된다. 근데 정작 "로그인 처리는 누가 해?" 라는 질문엔 이 클래스들이 답이 아니다. 그게 AuthService의 역할이다. JwtProvider는 토큰을 만들고 검증하는 도구다. 그러면 "언제 토큰을 만들어야 하는지" 판단하는 건 누가 해야 할까?바로 AuthService다.이 이메일로 가입된 회원이 있는지 확인비밀번호가 맞는지 검증다 통과하면 JwtProvider한테 "토큰 만들어줘" 요청이 과정이 비즈니스 로직이다. JwtProvider는 이런 판단 없이 그냥 토큰만 만.. 2026. 6. 9.