문제점
오늘은 SpringSecurity를 이용해 JWT를 이용한 로그인을 구현하던 중 200번으로 정상 실행이 되는데 로그인이 작동 되지 않고 JWT가 만료되었다는 에러가 발생했다. 분명 코드상으로는 로그인을하며 JWT를 생성해서 쿠키에 넣어주고, UserDetails를 Implement받은 객체에서도 토큰 만료기간이 없도록 설정 해주고 있기때문에, 에러가 발생하는 것이 이해되지 않았다.
시도해본 것
- 다른 DB상 아이디로 로그인 해보았다. 혹시 JWT가 바뀔까 싶어서 - 하지만 실패 같은 에러가 발생했다.
- 새로운 아이디를 회원가입 기능으로 가입해서 로그인 해보기 - 회원가입 기능도 200번으로 정상동작하지만 기능이 수행되진 않는 문제가 발생
- 튜터님에게 물어보고 라인에 걸어두고 디버그를 실행
해결
알고보니 그전에 공부하며 토큰을 Cookie에 등록해둔게 문제... 그 토큰이 쿠키에서 지워지지 않고 기본값으로 Post요청마다 같이 날아가고 있었던것, 그래서 코드는 예외처리하여 해당 토큰이 만료된 토큰이라고 반환한 정상적 동작을 한것
Postman에서 Cookie를 지워주고 다시 로그인하니 해결...
알게된 것
디버그 해보고 해당 메서드의 구현체를 찾아가는 방법을 알게됐다. 방법은 알아도 그렇게 찾아가서 디버그해본적이 없었는데, 튜터님이 상세히 디버그 하는방법을 같이 알려주셨다. 이 오류는 디버그가 아니었으면 에러코드도 나오지 않아 더 찾기 힘들었을거라고 하셨다.
에러가 났을 때 감잡히는게 없다면 디버그를 생활화 하자...
JWT의 장점
- JWT 의 주요한 이점은 사용자 인증에 필요한 모든 정보는 토큰 자체에 포함하기 때문에 별도의 인증 저장소가 필요 없습니다.
- 쿠키를 전달하지 않아도 되므로 쿠키를 사용함으로써 발생하는 취약점이 사라집니다.
- URL 파라미터와 헤더로 사용
- 트래픽 대한 부담이 낮음
- REST 서비스로 제공 가능
- 내장된 만료
- 독립적인 JWT
JWT의 단점
- Self-contained: 토큰 자체에 정보를 담고 있으므로 양날의 검이 될 수 있습니다.
- 토큰 길이: 토큰의 페이로드(Payload)에 3종류의 클레임을 저장하기 때문에, 정보가 많아질수록 토큰의 길이가 늘어나 네트워크에 부하를 줄 수 있습니다.
- Payload 인코딩: 페이로드(Payload) 자체는 암호화 된 것이 아니라, BASE64로 인코딩 된 것입니다. 중간에 Payload를 탈취하여 디코딩하면 데이터를 볼 수 있으므로, JWE로 암호화하거나 Payload에 중요 데이터를 넣지 않아야 합니다.
- Stateless: JWT는 상태를 저장하지 않기 때문에 한번 만들어지면 제어가 불가능합니다. 즉, 토큰을 임의로 삭제하는 것이 불가능하므로 토큰 만료 시간을 꼭 넣어주어야 합니다.
- Tore Token: 토큰은 클라이언트 측에서 관리해야 하기 때문에, 토큰을 저장해야 합니다.