인증에 대해서 공부하다가 이해가 되지 않았던 내용이 "왜 세션 기반 인증보다 JWT 인증이 모바일이나 IoT처럼 오프라인 상황이 벌어질 수 있는 곳에서 더 유용한지"였습니다.
이번 글은 해당 사항에 대한 내용을 나름대로 정리해보았습니다.
우선 오프라인 인증 상태란 무엇인지 알아야합니다.
오프라인 인증 상태란 서버와의 통신 없이 클라이언트가 인증된 상태로 간주할 수 있는 것을 의미합니다.
하지만 기억할 점은, 이 상태는 실제 서버와 연결되었을 때의 인증 상태와는 다르며, 클라이언트 단에서 제한된 기능만을 사용할 수 있도록 해줍니다. (주로 UI적인 부분)
왜 JWT 방식이 세션 방식에 비해 유리한지를 알려면 우선 각각의 방식에 대해서 간략하게라도 알아야합니다.
링크를 참고해도 좋습니다.https://wellsbabo.tistory.com/66
세션 기반 인증과 JWT
웹 애플리케이션에서 사용자 인증은 필수적인 요소로, 이것을 구현하기 위한 대표적인 방식으로 세션 기반 인증과 JWT(JSON Web Token) 기반의 인증을 주로 사용합니다. 세션 기반 인증세션 기반 인
wellsbabo.tistory.com
세션 방식
인증 상태를 서버에서 관리하며, 클라이언트는 세션 ID를 서버로 전송해 인증 상태를 확인합니다,
서버에 의존적이라 서버와 연결되지 않으면 인증 상태를 확인할 수 없으므로, 인터넷이 끊기면 인증된 상태로 기능을 사용할 수 없습니다.
JWT 방식
인증 정보를 JWT에 자체적으로 포함하고 있으므로, 클라이언트가 서버와 통신하지 않아도 JWT를 기반으로 인증된 상태로 '가정'할 수 있습니다.
JWT 토큰 자체에 인증 정보를 포함하므로, 서버와 연결되지 않아도 만료 전까지 클라이언트는 인증된 상태로 간주될 수 있습니다.
이러한 특징을 기반으로 비행기 모드처럼 오프라인 상황에서도 JWT를 통한 제한적인 기능(읽기 전용 데이터 보기 등)을 사용할 수 있습니다.
그럼 본격적으로 JWT의 오프라인 인증 작동 원리에 대해서 알아보겠습니다.
1. 서명 검증
클라이언트는 서버에서 제공받은 공개 키를 사용해 JWT가 위조되지 않았음을 확인할 수 있습니다.
공개 키를 통한 서명 검증만으로 JWT가 유효한지 판단할 수 있습니다.
클라이언튼 비밀 키를 몰라도 검증이 가능합니다. (공개키만 있기 때문에 JWT 수정이나 생성은 불가능)
2. 만료 시간(exp) 확인
JWT에는 만료 시간(exp 클레임)이 포함되어 있으므로, 클라이언트는 만료 여부를 확인해 인증 상태를 유지할 수 있습니다.
3. 오프라인에서 제공 가능한 기능
위의 특징으로 인해 클라이언트에서 기초적인 검증이 가능해져서 일부 제한된 기능을 제공할 수 있게 됩니다.
- 사용자의 프로필, 로컬 캐시에 저장된 데이터를 표시
- 인터넷 연결 없이도 "로그인 상태" 처럼 보이는 사용자 인터페이스 제공
이러한 JWT이 오프라인에서도 일부 검증 기능이 가능한 것과는 별개로 세션 방식은 한계가 있습니다.
- 세션 방식은 서버가 인증 상태를 관리하므로, 클라이언트가 항상 서버와 통신해야 합니다.
- 인터넷이 끊기면 세션 ID를 확인할 수 없으므로, 인증된 상태를 유지할 수 없습니다.
- 서버와 연결이 복구되기 전까지는 사용자가 제한적인 기능조차 사용할 수 없습니다.
이렇게 오프라인 환경을 고려할 때 JWT는 여러 장점을 갖고 있지만 주의할 점은 오프라인에서는 반드시 제한적인 작업만 해야한다는 것입니다.
결제, 데이터 수정과 같이 민감한 작업은 반드시 서버와 통신해 JWT를 검증하거나 추가적인 인증 절차를 거치게 만들어야 합니다!
이 내용을 정리하다가 또 하나의 의문이 들었습니다.
"그러면 온라인 상태에서 JWT는 클라이언트에서 1번, 서버에서 1번 총 2번의 검증을 거쳐야 하는건가?"
결론부터 이야기하면 당연히 서버에서 JWT를 검증하는 것이 일반적이고 핵심입니다.
클라이언트에서도 JWT를 검증할 수 있지만, 보안상 실제 중요한 작업에서는 서버 검증이 필수입니다.
온라인 상태에서의 JWT 검증 흐름에 대해서 좀 더 설명해보겠습니다.
클라이언트 JWT 검증
우선 클라이언트에서의 JWT 검증은 필요한 경우 1차적으로 JWT의 유효성을 검증할 수 있습니다.
클라이언트에서 검증을 하는 목적은 주로
- JWT가 변조되지 않았는지 확인
- JWT의 만료(exp) 시간이 지나지 않았는지 확인
그리고 클라이언트에서의 검증이 이루어지는 이유는 주로 UI/UX 개선 목적입니다.
예를 들어, 토큰이 만료되었을 때, 클라이언트에서 사용자에게 바로 메세지를 띄워주고 재로그인을 유도할 수 있습니다.
서버에서의 JWT 검증
서버는 항상 최종적으로 JWT를 검증해야합니다.
서버 검증은
- 근본적으로 해당 JWT가 유효한지
- 블랙리스트에 포함되어 있지는 않은지(강제로 로그아웃된 사용자)
- 요청에 포함된 데이터가 변조되지 않았는지
등을 확인합니다.
너무 당연한 이야기지만 클라이언트의 코드는 항상 해킹되거나 변조될 가능성이 있기 때문에 서버 검증은 필수적이며 클라이언트 검증만으로 실행되는 기능은 최소화해야 합니다.
그래서 정리하자면
클라이언트 검증은 할지 말지 선택할 수 있는 옵션 사항입니다. (사용자 경험 개선 목적)
- 토큰이 만료되었는지 미리 확인하고 사용자에게 알림
- 모바일 앱에서 "토큰이 만료되었습니다. 다시 로그인하세요."라는 메시지를 보여줌
- 클라이언트에서 1차적 확인을 하고 요청 자체를 차단해 불필요한 네트워크 요청을 줄일 수 있음
서버 검증은 필수입니다.
- 클라이언트가 요청한 JWT의 유효성을 최종적으로 확인
- 블랙리스트 확인 등 추가 보안 검사를 수행
그래서 대부분의 경우, 클라이언트에서의 JWT 검증은 생략하고 서버에서만 검증하는 경우가 많습니다.
왜냐면 결국 중요한 작업은 서버에서 검증을 해야하기 때문에 클라이언트에서의 검증은 보안성이 높지 않기 때문입니다.
굳이 클라이언트에서의 검증을 활용하는 경우라면, 클라이언트가 오프라인에서도 어느정도 동작해야 하거나, 빠른 피드백 (토큰 만료 등)이 필요한 경우에는 사용하기도 합니다.
하지만 민감한 작업은 반드시 서버에서 추가 검증을 거쳐야 합니다.
'방구석 컴퓨터 > 방구석 보안' 카테고리의 다른 글
세션 기반 인증과 JWT (2) | 2024.11.18 |
---|---|
Log4 (0) | 2022.03.19 |