인증이 필요한 이유?
보통 하나의 서비스 안에서는 여러명의 사용자가 존재한다. 특정 사용자마다 보유하고 있는 정보와 콘텐츠 역시 모두 다르다. 따라서 서버에서는 특정 사용자의 요청을 정확히 구분하고 권한에 맞는 정보를 제공하거나 서비스로직을 처리해야 한다.
HTTP는 본래 정보를 유지하지 않는 statless(비연결성)한 특성을 가지는데, 이때 각 통신의 상태가 저장되지 않기 때문에 웹사이트에서 인증을 관리하기 위한 방법이 필요하다.
서버가 클라이언트의 인증을 확인하는 방식은 크게 3가지가 있다.
- Cookie 인증
- Session 인증
- Token 인증
인증 유지
- 사용자가 사이트에 한 번 로그인 한 이후 특정 시간 내에는 다시 로그인하지 않아도 사용자의 로그인 상태를 계속 유지시켜줘야 한다.
- 이러한 인증 유지 개념은 처음 서버에 접속 하였을 때 로그인 과정을 통해 인증 받은 사용자는 사용자의 권한 정보 등을 메모리 등 쉽고 빠르게 접근이 가능한 방식으로 보관하고, 로그인 된 사용자를 유일하게 식별할 수 있는 인증 키 등을 발급하여 이를 통해 계속 요청을 보내는 방식을 사용한다.
1. Cookie 인증 방식
- 쿠키는 클라이언트가 어떠한 웹사이트에 방문할 경우, 그 사이트의 서버를 통해 클라이언트의 브라우저에 설치되는
key-value
형식의 문자열 정보이다. 이는 각 사용자마다 브라우저에 정보를 저장하니 고유 정보 식별이 가능하다.
- 과정
- 브라우저(클라이언트)가 서버에게 Request한다.
- 서버는 클라이언트 측에 쿠키 정보를
Set-Cookie
에 담아 Response한다.
- 이후 해당 클라이언트는 요청을 보낼 때마다, 매번 저장된 쿠키를 요청 헤더의 Cookie에 담아 보낸다. 서버는 쿠키에 담긴 정보를 바탕으로 해당 요청의 클라이언트가 누군지 식별하거나 정보를 바탕으로 추천 광고를 띄우거나 한다.
- 단점
- 사용자의 고유한 인증 정보인 쿠키를 요청 시 그대로 보내기 때문에 보안에 취약하다.
- 쿠키는 용량 제한이 있어 사이즈가 커질 수록 네트워크의 부하가 심해진다. → 이는 서버의 자원을 전혀 사용하지 않고, 클라이언트가 인증 정보를 책임 지게 되는 것을 의미한다. → 이처럼 클라이언트에 모든 인증 정보가 담겨 있다면 해커에 의해 Http Request 정보를 탈취 당했을 경우 사용자 정보는 바로 유출되는 것이다.
- 웹 브라우저마다 쿠키에 대한 지원 형태가 다르기 때문에 브라우저간 공유가 불가능하다.
2. Session 인증 방식
- 쿠키 인증 방식의 단점인 보안적인 이슈 때문에, 세션 인증 방식에서는 클라이언트의 정보를 서버 측의 메모리 또는
캐시
에 저장하고 관리한다.
- 세션 객체는 Key에 해당하는
Session id
와 이에 대응하는 Value
로 구성되어 있다. Value에는 세션이 생성된 시간, 마지막 접근 시간 및 User가 저장한 속성 등이 Map 형태로 저장된다.
-
과정
- 클라이언트가 웹사이트에서 로그인을 하면 세션 정보가 서버의 메모리(혹은 DB)에 저장된다. 이때 세션을 식별할 수 있는 고유
Session ID
를 기준으로 정보를 저장한다.
- 서버에서
Session ID
를 쿠키에 담아 브라우저로 전달한다. → 즉, 세션과 쿠키는 완전히 분리된 개념이 아니며 세션은 쿠키를 기반으로 한다.)
- 브라우저는 모든 Request에 쿠키에 담겨 있는
Session ID
를 함께 전송한다.
- 서버는 클라이언트가 보낸
Session ID
와 서버 메모리로 관리하고 있던 Session ID
를 비교하여 인증을 수행한다.
-
단점
- 쿠키에 포함된 Seeion ID 자체는 유의미한 개인정보를 담고 있지는 않는다. 하지만 해커가 Session ID 자체를 탈취하여 클라이언트인척 위장을 할 수 있는 문제가 발생한다.
- 서버에서 세션을 저장하고 있으므로 요청이 많아지면 서버에 부하가 심해질 수 있다.
3. Token 인증 방식 → JWT 토큰
- 클라이언트가 서버에 접속을 하면 서버에서 해당 클라이언트에게 인증되었다는 의미로
토큰
을 부여한다.
- 이 토큰은 유일하며 토큰을 발급받은 클라이언트는 또 다시 서버에 요청을 보낼 때 요청 헤더에 토큰을 심어서 보낸다.
-
과정
-
클라이언트가 아이디와 비밀번호로 로그인(인증)에 성공하면 서버는 클라이언트에게 토큰을 발급한다. 이때 발급된 토큰은 ‘유일’하며 인증이 되었다는 것을 의미한다.
-
클라이언트는 서버 측에서 전달 받은 토큰을 쿠키나 스토리지에 저장해 두고, 서버에 요청을 할 때마다 해당 토큰을 HTTP의 Authorizaation Request header
에 포함시켜 전달한다.
-
서버에서는 전달 받은 토큰을 먼저 제공 했던 토큰과의 일치여부를 검증하고 Response 한다.
토큰에는 요청한 사람의 정보가 담겨있기 때문에 서버는 DB를 조회하지 않고 누가 요청하는지 알 수 있다.
-
단점
- 쿠키/세션과 다르게 토큰 자체의 데이터 길이가 길어, 인증 요청이 많아질수록 네트워크 부하가 심해질 수 있다.
- Payload 자체는 암호화되지 않기 때문에 사용자의 중요한 정보는 담을 수 없다.
- 토큰을 탈취 당하면 노답이다. → 따라서 토큰의 시간을 제한하는 식으로 극복한다.
-
세션과 토큰의 차이점?
- 세션 기반 인증이 인증 정보를 서버에 저장하는 방식이라면, 토큰 기반 인증은 사용자가 인증 정보를 직접 들고 있는 방식이다.
JWT란?
- JWT란 Json Web Token의 약자로, JSON으로 만들어진 인증 관련 정보들을 암호화(Base64 URL-safe Encode, 즉 인코딩) 시킨 토큰을 의미한다.
- 토큰 내부에는 위변조 방지를 위해 개인키를 통한 전자 서명도 들어있다.
- JWT 기반 인증은 JWT 토큰(Access Token)을 HTTP Header에 실어 서버가 클라이언트를 식별하는 방식이다.
- 따라서 JWT를 서버로 전송하면 서버는 서명을 검증하는 과정을 거치게 되며 검증이 완료되면 요청한 응답을 돌려준다.
- JWT는
Header
, Payload
, Signature
3부분으로 이루어져 있으며 각각의 구성요소는 .
으로 연결되어 있다.
- Header와 Payload는 JSON 기반의 Key-value 형태로 구성되어 있고, Signature는 Header와 Payload를 기반으로 생성된다.
- 토큰의 헤더는 typ과 alg 두 가지 정보로 구성된다.
- typ : 토큰의 유형을 지정
ex) JWT
- alg : 서명 암호화 알고리즘 방식을 지정하며, 서명 및 토큰 검증에 사용
ex) “HS256”
Payload
- 토큰에서 사용할 정보의 조각들인 클레임(Claim)이 담겨 있다. 즉, 서버와 클라이언트가 주고받는 시스템에서 실제 JWT를 통해서 알 수 있는 데이터를 의미한다.
- 클레임은 총 3가지로 나누어지며, Json(key-value) 형태로 다수의 정보를 넣을 수 있다.
- Registered claims : 미리 정의된 클레임
- Public claims : 사용자가 정의할 수 있는 클레임 공개용 정보 전달을 위해 사용
- Private claims : 해당하는 당사자들 간에 정보를 공유하기 위해 만들어진 사용자 지정 클레임. 외부에 공개되도 상관없지만 해당 유저를 특정할 수 있는 정보들을 담는다.
Signature
- 서명은 토큰을 인코딩하거나 유효성 검사를 할 때 사용하는 고유한 암호화 코드이다.
- 시그니처에서 사용하는 암호화는 헤더에서 정의한 암호화 방식을(alg) 활용한다.
- secret key를 가지고 있으므로 이가 유출되지 않는 이상 복호화가 불가능하다. → 토큰의 위변조 여부를 확인하는데 사용된다.
Rerference
https://inpa.tistory.com/entry/WEB-📚-JWTjson-web-token-란-💯-정리
https://www.popit.kr/jwt-인증은-무엇이고-어떻게-사용해야-할까/
https://surprisecomputer.tistory.com/36