Skip to content

Conversation

@Hexeong
Copy link

@Hexeong Hexeong commented Jan 15, 2026

완료 작업 목록

  • 기존은 regitstration 이후 자동으로 로그인 되도록 구현되어 있으나, regitstration 이후 로그인 페이지로 이동하도록 수정해야 한다.
  • 지원하지 않는 타입을 업로드하는 걸 막아야 한다.
  • 업로드한 파일에 대해서 Payload 크기에 대한 제한으로 방어로직 구현
  • /user/info 요청에 대해 html에서 둘의 값이 같지 않으면 전송하지 않도록 바꿔야 함.
  • [Readme.md](http://Readme.md) 정리
  • JavaDoc으로 Github Pages 만들기

구현하며 고민했던 내용

  • 지원하지 않는 파일을 올리는 사용자에 대해서
    • 당연히 서비스 로직 상에서 이미지 외의 업로드 파일을 염두해두지 않고 만들었기에 서버에서 지원하는 이미지 파일이 아닌 경우, 사용자에게 올리지 말라고 해야 합니다.

    • 때문에 해당 요청을 거부하는 로직을 어디서 구현할지 고민했습니다.

    • 원래 MultipartFile에 대해서 body를 해석하는 부분을 ArgumentResolver에서 구현했으니, 해석이 끝나고 지원하는 타입이 아니라면 예외를 발생시키면 되겠다 싶었습니다.

    • 하지만, 구현할수록 ArgumentResolver의 책임이 너무 크다는 느낌이 들더군요..

    • 그래서 이걸 저는 새로 Interceptor 구현체를 만들어 요청 차단을 하기로 했습니다.

      • 구현 방식으로는 정규표현식으로 filename=\"(.*?)\"" 을 써서 group안에 들어있는 텍스트를 검사하는 방식으로 구현했습니다.
      public class FileUploadSafetyInterceptor implements Interceptor{
      
          private static final String COOKIE_HEADER_KEY = "Set-Cookie";
          private static final String HEADER_LOCATION = "Location";
          private static final Pattern FILENAME_PATTERN = Pattern.compile("filename=\"(.*?)\"");
          private static final String MY_DOMAIN = "http://localhost:8080";
      
          @Override
          public boolean preHandle(HttpRequest req, HttpResponse res, Object handler) throws CustomException {
              if (handler instanceof HandlerMethod hm) {
                  boolean flag = false;
                  for (Parameter params : hm.getHandlerMethod().getParameters()) {
                      if (params.isAnnotationPresent(MultipartFormdata.class)) {
                          flag = true;
                          break;
                      }
                  }
                  if (flag) {
                      Matcher matcher = FILENAME_PATTERN.matcher(req.bodyText());
                      while (matcher.find()) {
                          String originalFilename = matcher.group(1);
                          if (originalFilename == null || originalFilename.isBlank()) {
                              continue;
                          }
      
                          if (!UploadableFileType.isAllowed(originalFilename)) {
                              String redirectPathOnFail = req.headers().getOrDefault("referer", "/");
                              if (!redirectPathOnFail.startsWith(MY_DOMAIN))
                                  redirectPathOnFail = "/";
      
                              res.setStatus(HttpStatus.FOUND);
                              res.addHeader(HEADER_LOCATION, redirectPathOnFail);
      
                              String encodedMsg = URLEncoder.encode("업로드를 지원하지 않는 이미지 파일 형식입니다.", StandardCharsets.UTF_8);
                              res.addHeader(COOKIE_HEADER_KEY, "alertMessage=" + encodedMsg + "; Path=/");
                              throw new CustomException(ErrorCode.NOT_SUPPORTED_FILE_TYPE);
                          }
                      }
                  }
              }
              return true;
          };
      }
    • 다음과 같이 구현하여 성공적으로 지원하는 업로드 이미지 파일 형식이 아니라면 차단하는 로직을 완성했습니다.

      • 구현하고 나니 모든 요청에 대해 Interceptor의 대상인지를 검사하는 로직이 많이 비효율적으로 보이네요.. HandlerExecutionChain을 넘겨줄 때, 지원하면 넘겨주는 방식으로 구현해도 될 것 같다는 생각입니다. 추후 시간이 나면 한번 작업해보겠습니다!
      • 또한, 현재 구조가 Http 메시지를 파싱할 때, body 전체를 String 타입으로 저장하다 보니, 영상 같은 body가 무거워지는 경우에 대해서는 메모리 상에서 문제가 될 것 같은 느낌이 드네요…

AI 도움 받은 부분

  • 버그를 찾는 과정과 HTML 코드 수정하는 과정에서 AI의 도움을 받았습니다!

Hexeong and others added 9 commits January 15, 2026 15:22
* refactor: ARTICLE 테이블의 필요없는 commentCnt 필드 제거

Signed-off-by: Hexeong <[email protected]>

* refactor: BAD_REQUEST 에러코드 추가

Signed-off-by: Hexeong <[email protected]>

* feat: Article, Comment 모델의 setter, toString 메서드 추가

Signed-off-by: Hexeong <[email protected]>

* feat: ArticleDao의 메서드 추가 및 삭제
- decreaseLikeCnt 메서드 삭제
- articleId로 해당 게시물이 생성일자 기준 내림차순으로 몇 번째 index인지 반환하는 findIndexByArticleId 메서드 구현

Signed-off-by: Hexeong <[email protected]>

* feat: Article관련 Http 요청 핸들러 로직 추가
- 게시물 등록 요청 처리 핸들러 추가
- 게시물 좋아요 요청 처리 핸들러 추가

Signed-off-by: Hexeong <[email protected]>

* feat: Comment관련 Http 요청 핸들러 로직 추가 및 변경
- 댓글 등록시 articleId을 사용할 수 있도록 comment/index.html 렌더링시 model에 articleId를 넘겨주는 방식으로 리팩토링
- 댓글 등록 처리 핸들러 구현

Signed-off-by: Hexeong <[email protected]>

* refactor: index.html 수정
- comment/index.html이 정상적으로 댓글 등록 요청을 보내도록 수정
- /index.html과 main/index.html이 좋아요 요청을 보내도록 수정

Signed-off-by: Hexeong <[email protected]>

* refactor: HttpResponse의 헤더 구조를 동일 헤더 키(Set-Cookie 등)를 사용 가능한 구조로 변경

Signed-off-by: Hexeong <[email protected]>

* refactor: 변경된 HttpResponse 헤더 구조에 맞게 addHeader 메서드를 사용하도록 변경

Signed-off-by: Hexeong <[email protected]>

* refactor: HandlerMethod에서 던지는 Exception에 대해서 모두 커버가 가능하도록 throws 구문과 catch 구문 수정

Signed-off-by: Hexeong <[email protected]>

* feat: 로그인 결과에 따른 안내 메시지 기능을 쿠키와 model을 사용해 구현
- login/index.html에 js로 alert 메세지 실행 부분 작성
- DynamicPageHttpHandler에 리다이렉트에서 넘어온 쿠키 값을 model에 주입하도록 로직 추가
- UserHttpHandler에서 리다이렉트시 message를 쿠키로 넘기도록 로직 추가

Signed-off-by: Hexeong <[email protected]>

* refactor: 회원가입 처리 과정에서 각 필드 값의 최소 길이 검증과 ID/닉네임 중복 검증에 대한 로직 추가
- ErrorCode에 REGISTRATION_FIELD_ERROR 추가
- UserHttpHandler에서 검증 로직 추가
- UserDao에 findByName 메서드 추가
- DynamicPageHttpHandler에 회원가입 페이지의 alert 메시지를 model로 주입하도로 수정

Signed-off-by: Hexeong <[email protected]>

* fix: 요청한 pageNum이 totalCount 이상일 때에 대한 방어로직 추가

Signed-off-by: Hexeong <[email protected]>

* fix: 업로드한 게시물이 존재하지 않을 때, 게시물 블럭이 보이지 않도록 방어 로직 추가

Signed-off-by: Hexeong <[email protected]>

* refactor: FormData의 지원 대상을 Formdata 어노테이션으로 지정하도록 리팩토링

Signed-off-by: Hexeong <[email protected]>

* feat: ErrorCode 추가

Signed-off-by: Hexeong <[email protected]>

* feat: 이미지 파일을 보내고 렌더링 하는 html 코드 추가

Signed-off-by: Hexeong <[email protected]>

* feat: multipart/form-data Content-Type에 대해서 FormdataArgumentResolver가 잘 처리하도록 로직 추가
- Article 생성에 대한 정보를 담을 Request 객체 생성
- BodyParser가 기본 인코딩 타입인 ISO-8859-1를 사용해 인코딩하도록 변경
- FormDataArgumentResolver가 MultipartFile 요청을 잘 resolve하도록 처리 로직 추가
- MultipartFile 클래스와 MultipartFormdata 어노테이션 생성

Signed-off-by: Hexeong <[email protected]>

* feat: Article에 imageUrl 필드 추가

Signed-off-by: Hexeong <[email protected]>

* refactor: ArticleCreateRequest가 정상적으로 처리되도록 Handler 로직 수정

Signed-off-by: Hexeong <[email protected]>

* feat: User의 Profile 파일에 대해서 DB 컬럼 추가 및 mypage 프로필 및 정보 수정 핸들러 구현

Signed-off-by: Hexeong <[email protected]>

* test: 바뀐 스펙에 따른 이전 테스트 코드 삭제

Signed-off-by: Hexeong <[email protected]>

* test: ErrorCode, StaticResourceType 멤버 추가

Signed-off-by: Hexeong <[email protected]>

* refactor: username이 아닌 user 자체를 model에 주입하도록 리팩토링

Signed-off-by: Hexeong <[email protected]>

* refactor: User의 profileUrl을 JOIN해서 가져오도록 Article, ArticleDao 리팩토링

Signed-off-by: Hexeong <[email protected]>

* refactor: User의 profileUrl을 JOIN해서 가져오도록 Comment, CommentDao 리팩토링

Signed-off-by: Hexeong <[email protected]>

* refactor: User의 프로필 및 정보 업데이트 기능에 대해 잘 돌아가도록 html, css 파일 수정
- 추가로 ./ 경로로 참조하던 error.html에 대해 절대경로로 정적파일을 참조하도록 수정

Signed-off-by: Hexeong <[email protected]>

* refactor: User가 회원가입시 로그인되지 않고, 메인 화면이 아닌 로그인 화면으로 리다이렉트 되도록 구현

Signed-off-by: Hexeong <[email protected]>

* feat: 지원되지 않는 이미지 파일 업로드에 대해 요청을 차단하는 Interceptor 구현
- 지원하는 이미지 파일 목록에 대한 enum 클래스 생성
- 해당 enum을 기준으로 요청을 검사하는 Interceptor 구현
- 415 HttpStatus 추가

Signed-off-by: Hexeong <[email protected]>

* refactor: 예시 데이터에 대해 image 파일 추가

Signed-off-by: Hexeong <[email protected]>

* refactor: mypage 화면에서 입력한 비밀번호와 비밀번호 확인 값이 다를 경우 요청이 보내지지 않도록 제한하게 수정

Signed-off-by: Hexeong <[email protected]>

* fix: javaDoc 생성 과정에서 처리 되지 못하는 주석 문자 제거

Signed-off-by: Hexeong <[email protected]>

* feat: JavaDoc 생성

Signed-off-by: Hexeong <[email protected]>

---------

Signed-off-by: Hexeong <[email protected]>
@Hexeong Hexeong self-assigned this Jan 16, 2026
@Hexeong Hexeong added 3-1 3-2 and removed 3-1 labels Jan 16, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant