프로젝트를 진행할 때 사용자들의 접근성을 생각하여 보통 카카오로그인을 구현해서 이용할 수 있게 했다.
이후에 자동로그인이나, 세션을 이용하여 라우터 보호를 활용하다가, 여러 방식의 로그인 인증 방식들을 알게되어 알아보고자 정리하려한다.
참고사이트
https://inpa.tistory.com/entry/WEB-📚-JWTjson-web-token-란-💯-정리 [Inpa Dev 👨💻:티스토리]
https://dsc-sookmyung.tistory.com/313
로그인 인증 방식에는 대표적을 위 3가지 방식이 있다. 각 방식의 특징을 먼저 정리해보자
쿠키는 Key - Value 형식의 문자열 덩어리다
클라이언트가 어떠한 웹사이트를 방문할 경우, 그 사이트가 사용하고 있는 서버를 통해 클라이언트의 브라우저에 설치되는 작은 기록 정보 파일이다. 각 사용자마다의 브라우저에 정보를 저장하니 고유 정보 식별이 가능한 것이다.
첫 로그인 때 서버는 클라이언트의 응답 헤더에 set-cookie를 설정하고, 이후 클라이언트가 서버에 요청할 때 마다 헤더에 쿠키를 담아서 클라이언트를 식별함
쿠키는 사용자 데이터를 클라이언트에 저장함
1. 브라우저(클라이언트)가 서버에 요청(접속)을 보낸다.
2. 서버는 클라이언트의 요청에 대한 응답을 작성할 때, 클라이언트 측에 저장하고 싶은 정보를 응답 헤더의 Set-Cookie에 담는다.
3. 이후 해당 클라이언트는 요청을 보낼 때마다, 매번 저장된 쿠키를 요청 헤더의 Cookie에 담아 보낸다.서버는 쿠키에 담긴 정보를 바탕으로 해당 요청의 클라이언트가 누군지 식별하거나 정보를 바탕으로 추천 광고를 띄우거나 한다.
클라이언트가 페이지를 요청한다. (사용자가 웹사이트 접근)
웹 서버는 쿠키를 생성한다.
생성한 쿠키에 정보를 담아 HTTP 화면을 돌려줄 때 같이 클라이언트에게 돌려준다.
넘겨 받은 쿠키는 클라이언트가 가지고 있다가(로컬 PC에 저장),
다시 서버에 요청할 때 요청과 함께 쿠키를 전송한다.
동일 사이트 재방문시 클라이언트의 PC에 해당 쿠키가 있는 경우,
요청 페이지와 함께 쿠키를 전송한다.
이러한 쿠키의 보안적인 이슈 때문에, 세션은 비밀번호 등 클라이언트의 민감한 인증 정보를 브라우저가 아닌 서버 측에 저장하고 관리한다. 서버의 메모리에 저장하기도 하고, 서버의 로컬 파일이나 데이터베이스에 저장하기도 한다.
핵심은 민감한 정보는 클라이언트에 보내지말고 서버에서 모두 관리한다는 점이다
sessionID를 쿠키에 저장하고 서버에는 sessionID를 통해 클라이언트를 식별한다.
세션은 서버측에서 관리함
1. 유저가 웹사이트에서 로그인하면 세션이 서버 메모리(혹은 데이터베이스) 상에 저장된다. 이때, 세션을 식별하기 위한 Session Id를 기준으로 정보를 저장한다.
2. 서버에서 브라우저의 쿠키에다가 Session Id를 저장한다.
3. 쿠키에 정보가 담겨있기 때문에 브라우저는 해당 사이트에 대한 모든 Request에 Session Id를 쿠키에 담아 전송한다.
4. 서버는 클라이언트가 보낸 Session Id 와 서버 메모리로 관리하고 있는 Session Id를 비교하여 인증을 수행한다.
클라이언트가 서버에 접속 시 세션 ID를 발급 받는다.
클라이언트는 세션 ID에 대해 쿠키를 사용해서 저장하고 가지고 있는다.
클라리언트는 서버에 요청할 때, 이 쿠키의 세션 ID를 같이 서버에 전달해서 요청한다.
서버는 세션 ID를 전달 받아서 별다른 작업없이 세션 ID로 세션에 있는 클라언트 정보를 가져와서 사용한다.
클라이언트 정보를 가지고 서버 요청을 처리하여 클라이언트에게 응답한다.
토큰 기반 인증 시스템은 클라이언트가 서버에 접속을 하면 서버에서 해당 클라이언트에게 인증되었다는 의미로 '토큰'을 부여한다. 이 토큰은 유일하며 토큰을 발급받은 클라이언트는 또 다시 서버에 요청을 보낼 때 요청 헤더에 토큰을 심어서 보낸다. 그러면 서버에서는 클라이언트로부터 받은 토큰을 서버에서 제공한 토큰과의 일치 여부를 체크하여 인증 과정을 처리하게 된다.
기존의 세션기반 인증은 서버가 파일이나 데이터베이스에 세션정보를 가지고 있어야 하고 이를 조회하는 과정이 필요하기 때문에 많은 오버헤드가 발생한다. 하지만 토큰은 세션과는 달리 서버가 아닌 클라이언트에 저장되기 때문에 메모리나 스토리지 등을 통해 세션을 관리했던 서버의 부담을 덜 수 있다. 토큰 자체에 데이터가 들어있기 때문에 클라이언트에서 받아 위조되었는지 판별만 하면 되기 떄문이다.
토큰은 앱과 서버가 통신 및 인증할때 가장 많이 사용된다. 왜냐하면 웹에는 쿠키와 세션이 있지만 앱에서는 없기 때문이다.
요약하자면,서버의 부담을 줄이기 위해 등장한 인증방식이 토큰이다
1. 사용자가 아이디와 비밀번호로 로그인을 한다.
2. 서버 측에서 사용자(클라이언트)에게 유일한 토큰을 발급한다.
3. 클라이언트는 서버 측에서 전달받은 토큰을 쿠키나 스토리지에 저장해 두고, 서버에 요청을 할 때마다 해당 토큰을 서HTTP 요청 헤더에 포함시켜 전달한다.
4. 서버는 전달받은 토큰을 검증하고 요청에 응답한다. 토큰에는 요청한 사람의 정보가 담겨있기에 서버는 DB를 조회하지 않고 누가 요청하는지 알 수 있다.
쿠키/세션과 다르게 토큰 자체의 데이터 길이가 길어, 인증 요청이 많아질수록 네트워크 부하가 심해질수 있다.
Payload 자체는 암호화되지 않기 때문에 유저의 중요한 정보는 담을 수 없다.
💡 payload?
데이터 전송시 실제 데이터 부분이 들어가 있는 부분 Header, payload로 나뉜다
토큰을 탈취당하면 대처하기 어렵다. (따라서 사용 기간 제한을 설정하는 식으로 극복한다)
위 세가지를 종합하면
쿠키/세션
세션아이디를 헤더에 있는 쿠키에 담아 보낸 후, 서버에서 세션아이디를 이용해 세션DB에 있는 유저를 식별한다
그러니까 쿠키는 세션아이디를 전달하기 위한 매개체를 이용한 방식이다. 하지만 이 방식은 DB의 리소스가 더 필요하게 되고 서버 부하도 심해진다.
토큰
일단 DB가 따로 더 필요하지 않다. 서버에서 유효성만 검사하여 사용자를 식별하여 인증해주는 방식
실질적으로 사용되는 데이터인 payload는 암호화되지 않기때문에 탈취 당할 위험이 있어 중요한 정보를 담을 수 없다