1. 어려웠던 부분 

  • 서비스 배포 후 몇몇 유저들이 카카오로그인을 하면 'JWT토큰이 만료되었습니다.' 라는 오류 메세지와 함께 계속해서 튕기는 오류가 있었다. 왜 우리 팀원들이 할 때는 잘 되는데 안되지?라고 다시 카카오 로그인을 하나씩 뜯어보니 로그인 시 이메일 허용이 선택사항으로 되어있었는데, 이 부분을 체크하지 않으면 위와 같은 오류가 떴던 것이었다. 
  • 이를 해결하기 위해 Kakao Developers 의 내 애플리케이션 - 카카오로그인 - 동의항목 에서 이메일이 선택동의로 되어있었다. 이 부분을 필수동의로 바꿔주니 해당 오류가 해결 되었다! 호 ~ 

 

2. 느낀 점 : 

  • 서비스 배포를 통해 코드만 잘 짜서 되는게 아니라 환경설정이 참 중요하다는 것을 배우고 있다. AWS, 소셜로그인, 깃헙액션 등 설정을 잘 해줘야 한다. 그리고 구글 설문폼이나 서비스 내부에 플러그인으로 넣어주는 고객서비스 개념의 채팅 서비스 같은 부수적인 부분, UX적인 부분 등 많은 부분들이 잘 갖춰져야 하나의 완성된 서비스가 된다. 

 

3. 새로 알게 된 내용 :

  • 서비스 배포를 통해 코드만 잘 짜서 되는게 아니라 환경설정이 참 중요하다는 것을 배우고 있다. AWS, 소셜로그인, 깃헙액션 등 설정을 잘 해줘야 한다. 그리고 구글 설문폼이나 서비스 내부에 플러그인으로 넣어주는 고객서비스 개념의 채팅 서비스 같은 부수적인 부분, UX적인 부분 등 많은 부분들이 잘 갖춰져야 하나의 완성된 서비스가 된다. 
 

4. 셀프칭찬 (오늘 잘한 일) 

  • 이번 프로젝트에 내가 담당한 부분이 많지 않아서 그래도 담당한 부분이라도 잘 처리하고 싶었는데, 어느정도 마무리가 잘 된 것 같다.
  • 내일 있을 멘토링 자료를 준비하면서 다시한번 우리 서비스에서 사용된 기술들과 의사결정 과정들을 정리했다. 

 

5. 내일 할 일 : 기술멘토링 ! 멘토링 후 피드백 반영하기.

토큰 생명주기 관리를 위해 Redis TTL(Time To Live) 기능을 사용하는 방향으로 수정해 보았다.

TTL기능을 사용하기 위해선 CrudRepository를 상속받아야 한다. 그래서 수정된 코드는 아래와 같다!

 

1. RefreshToken (entity)

// 기능 : Redis에 Refresh Token 저장
@Getter
@Setter
@NoArgsConstructor
@RedisHash(value = "refreshToken", timeToLive = 7 * 24 * 60 * 60L ) // 초단위 = 7일
public class RefreshToken {
    @Id
    private String email;
    private String refreshToken;

    public RefreshToken(String email, String token) {
        this.refreshToken = token;
        this.email = email;
    }

    public RefreshToken updateToken(String token) {
        this.refreshToken = token;
        return this;
    }
}

 

2. RefreshTokenRepository

@Repository
public interface RefreshTokenRepository extends CrudRepository<RefreshToken, String> {
    void deleteById(String email);
}

 

3. RefreshTokenRepository

// 기능 : Redis에 Refresh Token 저장
@Service
@RequiredArgsConstructor
public class RefreshTokenService {
    private final RefreshTokenRepository refreshTokenRepository;

    // 특정 RefreshToken 조회
    public RefreshToken findByEmail(String email){
        return refreshTokenRepository.findById(email).orElseGet(
                ()-> null
        );
    }

    // RefreshToken 저장
    public void saveRefreshToken(RefreshToken refreshToken){
        RefreshToken refreshToken1 = new RefreshToken(refreshToken.getEmail(), refreshToken.getRefreshToken());
        refreshTokenRepository.save(refreshToken1);
    }

    // RefreshToken 삭제
    public void deleteRefreshToken(String email){
        refreshTokenRepository.deleteById(email);
    }
}

 

 

전체 코드는 아래 깃헙을 참고해 주세요 : ) ! 

https://github.com/namoldak/Backend

 

GitHub - namoldak/Backend

Contribute to namoldak/Backend development by creating an account on GitHub.

github.com

 

 

 

 

1. 어려웠던 부분 

  • 오늘 드디어 프론트엔드 팀원분과 그동안 작성하고 기다리고 있던 리프레시토큰을 적용해보았다. 분명히 나는 헤더에 엑세스토큰과 리프레시토큰을 보냈는데, 쿠키엔 undifined 라고 떠서 어디서 막힌걸까 헤맸는데, 지나가는 시넌님이 개발자창의 Network tap을 활용하는 법을 알려주셨다. 네트워크탭을 확인해보니 다행히 백에서는 response header에 토큰을 잘 담아 보내주고 있었다. 프론트에서 쿠키에 set하는 과정에서 오류가 있었는데 이 부분을 수정한 뒤 잘 반영이 되었다. 비록 길을 잃어 삽질하느라 9시간이나 걸렸지만, 그래도 오늘 안에 나의 밀린 과제였던 리프레시 토큰을 해결해서 다행이다! 

 

2. 느낀 점 : 

  • 백엔드는 보통 디버깅을 할 때 log를 찍거나 디버깅을 하는데, 프론트단에서는 consol을 찍거나 개발자 창을 통해 확인을 한다. 개발자도구 inspect는 진짜 디버깅할 때 유용한 것 같다! 리엑트 코드를 나도 좀 더 이해할 수 있으면 작업이 정말 편할 것 같다. 언젠가 리액드를 공부해 보기로...! 

 

3. 새로 알게 된 내용 :

  • 블로그 글과 구글링을 통해 리프레시 토큰을 구현했다. 글들에 설명이 부족해서 처음에 도대체 토큰 재발급 api요청은 언제 어떤 방식으로 보내야 하는지 엄청 헤맸다.
  • 첫 시도는 사용자가 토큰 만료후 어떠한 요청을 보냈을 때 토큰만료 Status Code를 401번으로 서버에서 프론트로 응답했는데, 이 401 코드가 뜨면 프론트에서 해당 토큰재발급 api 요청을 보내는 것으로 설계했다. 그러나 어떤 이유에서 401번 코드가 먹히지가 않았다. 
  • 다음 방법은 현재 갖고 있는 액세스 토큰 만료시간 5분 전에 setTimeout()을 활용해서 요청을 보내는 것으로 수정했더니 정상 작동 하였다. 아래는 프론트에서 만료시간 전 토큰 재발행 요청을 하는 코드 일부분이다.
export const setAccessToken = (token) => {
  const expireDate = new Date();
  expireDate.setMinutes(expireDate.getMinutes() + 30);

  setTimeout(() => {
    instance.post('/auth/issue/token').then((response) => {
      setAccessToken(response.headers.accesstoken);
    });
  }, 25 * 60 * 1000);

  cookies.set(ACCESS_TOKEN, token, {
    path: '/',
    expires: expireDate,
  });
};

 

4. 셀프칭찬 (오늘 잘한 일) 

  • 항상 내가 할 수 있을까? 라는 생각으로 의심하고 걱정했는데, 그래도 오늘 리프레시 토큰이라는 과제를 끝내서 다행이라고 생각했다! 

5. 내일 할 일 : 버그수정, 토요일 멘토링 준비 ( 개념 공부 )

 

 

1. 어려웠던 부분 

  • 오늘 드디어 서비스 배포를 했다. 그런데 배포하자마자 엄청난 오류가 발생했다. 게임룸에서 나와도 웹소켓이 제대로 끊기지 않아서 콘솔창으로 확인했을 때 계속해서 채팅내용이 보이고, 또 게임방에 입장했을 때 갑자기 2개 3개로 입장이 되는 등.. 배포하자마자 오류를 발견해서 허겁지겁 고치기 시작했다.
  • 원인은 프론트단에서 웹소켓을 끊어주는 코드가 빠져있었다. 아래의 코드를 추가하고 에러 해결! 휴 진땀 났던 몇 시간 ;;
        .delete(`rooms/${param.roomId}/exit`)
        .then(async (res) => {
          socketRef.current.close();
          console.log('클라이언트', client.current);
          client.current.deactivate(); // 이 부분 추가
        })
        .catch(async (error) => {
          socketRef.current.close();
          client.current.deactivate(); // 이 부분 추가
        });
    };
  }, []);

 

2. 느낀 점 :  끝날때까지 끝난 게 아님

 

3. 새로 알게 된 내용 

  • 오늘 받은 피드백 중 콘솔 창에 찍히는 로그를 지워야 한다는 피드백이 있었다. 이제 개발 부분은 서서히 끝나다보니 보안 부분을 더 신경쓰게 되었다. 콘솔에 찍히는 로그도 지워주고, S3 엔드포인트를 가려주기도 하고, 또 토큰을 어디다 저장할지도 생각해보게 되고 하나가 끝났다고 끝난게 아니라 계속해서 버그를 찾고 발전시켜야 하는 코딩의 세계 ~_~

 

4. 셀프칭찬 (오늘 잘한 일) 

  • 오늘도 트러블슈팅으로 하나 더 배웠다 !

 

5. 내일 할 일 : 유저 피드백 반영해서 자잘한 버그 수정하기 ! 

 

 

1. 어려웠던 부분 

  • 오늘은 이런 저런 테스트를 하면서 자잘한 오류를 잡으면서 하루를 보냈다. 너무 사소한 오류들이라서 생각도 나지 않는다~_~ 피곤하다. 서비스 배포를 앞두고 구글 설문지 폼을 작성하고, 대외용 노션 페이지도 만들고, 홍보용 이미지와 카피라이터를 준비했다. 개발만 신경쓸게 아니라 서비스 하나를 만드는데 이것 저것 참 신경써야 할 부분이 많다.

 

2. 느낀 점 : 

  • 프로젝트 하나를 통해 정말 다양한 경험을 하는 것 같다. 기획부터 개발, 서비스 런칭 전 마케팅 준비까지. 덕분에 내가 어느 부분에서 더 흥미를 느끼고 잘 하는지 알게된 것 같다 : ) 

 

3. 새로 알게 된 내용 :

  • 구글 설문 폼 만드는 방법 (완전 쉬움 ! 아래 링크를 이용하기)

https://www.google.com/intl/ko_kr/forms/about/

 

Google Docs

Google Docs. 좋아하는 사람 57,329명 · 이야기하고 있는 사람들 262명. News and updates about Google Docs, Sheets, Slides, Sites, Forms, and more!

www.facebook.com

 

4. 셀프칭찬 (오늘 잘한 일) 

  • 지난 크리스마스도, 새해도, 설날도 그리고 오늘 내 생일도 항해99를 하며 보냈다. 이 시기가 지나고 나면 개발자가 되지 못하더라도 후회는 없을 것 같다. 마지막까지 후회 없이 잘 버티고 열심히 공부하자 ! 

 

5. 내일 할 일 : 드디어 서비스 배포 ! 

 

+ Recent posts