😮 서론
간단한 사이트들을 제외하고, 대부분의 사이트에서는 회원 기능이 존재합니다.
회원 정보를 통해서 가입된 사이트에 글을 쓰거나, 읽거나 댓글을 달거나 문의를 넣거나 등등
다양한 기능들을 사용할 수 있게 되는데요!
하지만, 페이지를 옮겨다닐 때마다 회원 인증을 진행하고, 껐다가 켰을 때마다 다시 인증을 진행하고
이런 일은 .. 제가 아는 사이트에선 존재하지 않습니다.
이처럼 인증을 유지하기 위한 방법 중 세션 방식과 토큰 방식에 대해 장단점을 알아보고 어떤 걸 사용할지 정해보도록 하겠습니다.
😏 본론
인증(Authentication) / 인가(Authorization)
기본 개념부터 잡고 가도록 하겠습니다.
인증(Authentication)
내가 누군지에 대해 사이트에 인증받는 걸 얘기합니다.
보통 ID/PW 를 통해 로그인을 진행합니다.
인가(Authorization)
허용된 권한을 얘기합니다.
예로 나라에서 발급한 신분증을 통해 내가 누구인지 나타낼 수 있는 것처럼
로그인 시 받은 인증정보로 나의 권한을 부여받은 걸 의미합니다.
이제 로그인을 통해 어떤 방식으로 나의 신분을 나타낼 수 있는지, 어떻게 인가(Authorization)를 진행할지 알아보겠습니다.
왜 이런 방법으로 인가를 진행해야 하지?
일단, 왜 이렇게 복잡하게 인가 기능을 해야 하는지에 대해 설명하겠습니다.
서론에서 이야기했듯 세션 or 토큰 방식을 사용하지 않고 그냥 로그인만 진행할 때에는
url을 이동할 때마다 로그인을 해야 하는 현상이 발생합니다.
그 이유는 HTTP는 Stateless 한 특징을 가지고 있기 때문입니다.
stateless 란 '비 상태 유지'를 의미합니다. 반대의 개념은 stateful '상태 유지'가 있습니다.
말 그대로 서버는 클라이언트의 연결을 유지하지 않는 걸 말합니다.
한 번 요청하면 연결을 끊기 때문에 각각의 요청은 연결된 게 아닌 개별로 판단하게 됩니다.
간단하게 이유에 대해서 설명드리자면,
만약 서버에서 상태를 유지하게 되면, 항상 같은 서버로 요청을 보내야 합니다.
반대로 유지하지 않게 되면, 어느 서버로 요청을 보내도 상관이 없게 됩니다.
장점으로, 클라이언트의 요청이 늘어남에 따라 유동적으로 서버의 수를 늘릴 수 있게 됩니다.
이러한 stateless 한 특징 때문에 우리는 세션 or 토큰을 통해 인가를 진행하여야 합니다.
(여기까지가 서론인가 봅니다..)
세션 (Session)
세션 장단점
세션은 서버에 저장되므로 관리자가 세션에 대한 권한을 갖습니다.
예를 들어 서버에서 계정이 손상된 것으로 의심되는 경우 세션 ID를 즉시 무효화하여 사용자가 즉시 로그아웃 되도록 할 수 있습니다.
반면에 세션은 서버에 저장되기 때문에 서버는 사용자가 보낸 세션 ID를 조회하는 역할을 합니다.
이것은 확장성 문제를 일으킬 수 있습니다.
쿠키는 사이트 간 요청 위조 공격에 노출될 수 있습니다.
공격자는 일부 JS 스크립트가 쿠키를 악용하여 서버에 악의적인 요청을 보낼 수 있는 적대적인 웹 사이트로 사용자를 오도할 수 있습니다.
또 다른 취약점은 공격자가 세션 ID를 가로채서 서버에 유해한 요청을 수행할 수 있는
중간자 (man-in-the-middle) 공격의 가능성과 관련이 있습니다.
세션 인증 모범 사례
- 무차별 대입 공격을 방지하기 위해 세션 ID를 길고 무작위로 유지하세요. 권장 길이는 128비트입니다.
- 민감한 데이터나 사용자별 데이터 없이 세션 ID를 기록합니다. 이상적으로 ID는 임의의 의미 없는 문자열이어야 합니다.
- HTTPS 통신을 시행합니다.
- 보안 및 HTTP - Only 속성으로 쿠키를 생성합니다.
- 브라우저를 닫거나 시간 초과, 로그아웃 또는 별도의 위치에서 로그인할 때 세션을 삭제합니다.
토큰 (Token)
토큰을 설명할 때 Access Token 만을 사용하여 설명도 많이 하곤 합니다.
하지만, Access Token의 단점을 보안하기 위해서는 Refresh Token은 필수라 생각하며
OAuth 표준에서 또한 Refresh Token을 적용하기 때문에 여기서는 합쳐서 설명하도록 하겠습니다.
토큰 장단점
DB 혹은 저장소를 조회하는 시간과 리소스는 생각보다 큽니다.
하지만, 토큰은 이미 권한 정보를 가지고 있기 때문에 별도로 조회하는 시간과 리소스를 절약할 수 있습니다.
세션 ID를 저장하는 쿠키 같은 경우 모바일과 원활하게 결합하지 않을 수 있지만, 토큰은 구현하기가 쉽습니다.
다만, 인증 내용은 클라이언트에 저장되기 때문에 서버는 세션 방식과 같은 특정 보안 작업을 수행할 수 없습니다.
또한 쿠키에 비해 토큰은 많은 정보를 포함하고 있기 때문에 길이가 훨씬 크며,
아직 유효한 토큰을 탈취당할 시 서버에 접근이 가능하게 됩니다.
토큰 인증 모범 사례
- JWT 토큰의 유효성을 검사하고 서명 알고리즘을 준수하지 않은 토큰을 거부합니다. 또한 모든 청구, 발급자, 만료 날짜 및 대상을 확인해야 합니다.
- 토큰에 만료 시간을 필수로 지정해주어야 합니다.
- HTTPS 통신을 진행해야 하며, 가로채거나 손상될 수 있는 비보안 연결을 통해 토큰을 보내지 않도록 합니다.
- 사용자의 중요한 정보를 토큰에 담으면 안 됩니다. 누구든 확인할 수 있습니다.
세션 토큰 차이점
세션 인증 방식 | 토큰 인증 방식 | |
인증 정보 저장 위치 | 서버 | 사용자 |
서버에 인증 보내는 것 | 쿠키 | 토큰 자체 |
사용자 요청 수행 작업 | 사용자가 쿠키와 함께 보낸 ID 덕분에 올바른 세션을 찾기 위해 데이터베이스에서 조회 | 사용자 토큰 암호 해독 및 서명 확인 |
서버에서 강제 로그아웃, 세부 정보 변경 작업 | O | X |
취약점 | 중간자 공격, XSS, CSRF, 무차별 대입공격 | 중간자, 토큰 도용, 비밀 키 위반 |
추천 방법 | 사용자 - 서버 연결 | 서버 간 연결 |
🥹 결론
최근에는 세션 방식보다 토큰 방식을 많이 사용하고 있습니다.
아마 OAuth 인증 방식이 많이 활용되면서 확장성이 높은 토큰 방식의 장점이 더욱 부각된다고 생각됩니다.
물론, 세션 방식을 사용하는 이유도 존재합니다.
예를 들어 넷플릭스에서 사용자를 제한하거나, 다른 디바이스에서 접속된 세션을 강제 로그아웃을 진행해야 하는 이유가 있을 땐
세션 방식을 사용해야 된다고 생각합니다.
단일 페이지인 경우 세션이 좀 더 효과적일 거라 생각하며,
웹이 아닌 모바일이나 다른 클라이언트, 외부 API 통신 등 여러 곳에서 인가를 진행해야 할 때에는
토큰 방식이 효과적일 거라 생각합니다.
잘못된 부분이나 추가되면 좋은 내용이 있다면 댓글로 알려주시면 감사하겠습니다!!
참고
'Network' 카테고리의 다른 글
[Network] 캐시(Cache) 알아보기 (0) | 2022.06.15 |
---|