[SEB_BE_43]프로젝트 회고

정윤호·2023년 5월 30일
0

4주간의 짧다면 짧고 길다면 긴 프로젝트기간이 마무리되었다. 프로젝트 기간동안의 겪었던 이슈와 공유하면 좋을 것, 타 팀의 프로젝트를 경험한 소감 등을 중심으로 회고를 작성해보고자한다.

메인 프로젝트 기간동안 프리 프로젝트와 동일하게 User와 시큐리티를 담당했다. 프리기간동안 마무리하지못한 부분과 깊이있게 공부해보고 싶은 마음에 지원하게되었고, 좋은 선택이었다고 생각이 된다.

1. 트러블슈팅 사례

① OAuth 2.0 리다이렉션

시큐리티를 구현하면서 가장 먼저 문제에 부딪힌 부분은 프리때 적용시도했다가 실패했었던 OAuth 2.0를 적용하면서 리다이렉션과 관련된 문제에 맞닿드리게되었다.

<출처 : 코드스테이츠 유어클래스 컨텐츠>

Spring Security를 활용해서 OAuth 2.0을 구분하다보니, 애플리케이션 서버(OAuth Client)와 인증 서버(Authorization Server)간의 주고 받는 통신을 이해하기가 어려워 리다이렉션 설정에 다소 애를 먹었다.
결론은 사용자(Resource Owner)는 "~/oauth2/authorization/{서비스ID}"로 인증 요청을 보내고, 애플리케이션과 인증서버의 리다이렉션 URL을 "~/login/oauth2/code/{서비스ID}"으로 설정하여 리다이렉션을 보내야했다.
프론트분과 열심히 삽질을 하며, 제대로 OAuth2.0의 흐름에 대해서 이해할 수 있었다.

② JWT RefreshToken으로 토큰 재발행

개념적으로 알고 있었던 RefreshToken을 활용한 토큰 재발행을 실제로 적용하려다보니, 여러 사항들에 대해서 부족함을 많이 느낄 수 있었다.
학습한 내용으로는 AccessToken과 RefreshToken 생성만 있고, 재발행하는 부분은 빠져있었다는 것을 뒤늦게 알게 되었다. 기존 코드를 활용해 RefreshToken으로 재발행하는 기능을 구현하고, 제대로 작동시키기 위해 검증기능을 추가하였다. 이와더불어 프론트분의 요청에 따라 로그인 정보를 바탕으로 UserId를 가져오는 유틸을 따로 구현하였다. 다만, 어렵게 삽질해서 구현한 유틸은 사실 학습하면서 배웠던 JWTokenizer에 이미 어느정도는 구현이 되어있었다.
아래의 코드는 열심히 삽질해서 구현한 코드이다.

public static Long getCurrentUserId() {
    Integer userIdFromToken;

    HttpServletRequest request = ((ServletRequestAttributes) Objects.requireNonNull(RequestContextHolder.getRequestAttributes())).getRequest();

    String secretKey = EnvConfig.getSecretKey();

    String authorization = request.getHeader("Authorization");

    if (authorization == null) {
        return null;
    }

    String tokenValue = authorization.replace("Bearer ", ""); // 요청 시 전달한 JWT value

    // JWT에서 추출한 인증 정보를 불러오기 위한 JWT Parser
    JwtParser jwtParser = Jwts.parserBuilder()
            .setSigningKey(secretKey.getBytes())
            .build();

    try {
        Jws<Claims> parsedJwt = jwtParser.parseClaimsJws(tokenValue);
        Map<String, Object> jwtClaims = new HashMap<>(parsedJwt.getBody());
        userIdFromToken = (Integer) jwtClaims.get("userId");   // JWT에 담겨 있는 인증 서비스로부터 받은 유저 ID 정보
    } catch (JwtException ex) {
        // JWT 파싱 실패 시 예외처리
        throw new BusinessLogicException(ExceptionCode.TOKEN_NOT_AVAILABLE);
    }
    return userIdFromToken.longValue();
}

유틸을 static으로 구현하다보니, 환경변수로 적용하여 사용하던 Secretkey를 활용하기 위해서 EnvConfig 설정파일을 빼내어 환경변수를 처리할 수 있도록 구현하였다. 많이 부족하지만 개인적으로 많은 부분을 깊이 있게 학습할 수 있어서 좋았다.

③ HTTPS 적용

프론트에서 Vercel을 활용하면서 https 적용이 필수적이게되었다. 계속해서 보안 경고가 뜨는 부분도 내심 걸리는 부분이었고 학습하고 싶었던 분야라서 적용을 시도하였다.
나름(?) 속성으로 적용한다고 AWS 로드밸런서를 이용한 방법을 활용하기위해 Route53에서 도메인을 조금 비싸게(5$) 구매하고 ACM(Aws Certificate Manager)로 SSL 인증서를 받고자 하였다.
그런데 무슨 이유에서인지 ACM 발급과정에서 계속 검증대기에서 넘어가지 않는 문제가 발생하였다. 멘토링을 통해 멘토님께 여쭈어보고, 본인도 처음 보는 문제라고하여 그럴때는 AWS Support를 적극 활용하신다하여 AWS측에 메일을 보냈으나,

과금하지않은 사용자라 해결을 받지는 못하고 열심히 삽질을 해서 문제를 해결하였다. 덕분에 DNS에 대해서 알게 되었다. 문제는 어떤 사유에서인지 모르겠지만 SOA레코드가 틀어져서 발생한 문제였다.

2. 프로젝트시 Tip

EC2를 프리티어로 사용하게되면 메모리 부족에 시달리게된다. 서버가 자주 다운되게 되고, 성능도 매우 떨어지게 된다. 이에 과금을 해야하나 고민하다가 발견한 방법이 스왑 메모리를 설정하는 것이다.
아래의 AWS re:Post의 글을 참조하여 적용하였다.
https://repost.aws/ko/knowledge-center/ec2-memory-swap-file

3. 타 팀 프로젝트 경험 소감

① 17팀 Uncover

일단 멋진 UI에 압도당했습니다. 그리고 서버측면에서 많은 음악을 다루는 것과 다양한 분류에 깜짝 놀랐다.
이 짧은 시간에 이정도 퀄리티가 가능하다는 것에 놀랄 뿐이었다.
다소 아쉬운 점이 있다면, 좋아요, 코멘트 등이 아직 구현되지 않은 부분이 아쉬웠다.

② 23팀 너의 MBTI는

좋은 컨셉과 디자인에 매료된 서비스이다. MBTI를 중심으로 여행지를 추천해주는 컨셉... 너무 좋다.
향후 서비스가 된다면 MBTI와 더불어 "아이와 함께", "펫 동반", "어르신 동반" 등 추가적인 사항까지 고려해서 맞춤형 여행지를 추천해주는 서비스로 발전하면 정말 좋을 것 같다는 생각이 들었다.

profile
오늘 하루도 최선을 다하자!!

0개의 댓글