인증을 통해 서비스는 유저를 검증할 수 있다.
인증을 만들어야 한다면 쿠키, 세션, 토큰, JWT라는 인증방법이 있는데 이것들을 알아보자.
쿠키(Cookie)
쿠키를 이용해서 서버는 나의 브라우저에 데이터를 넣을 수 있다.
나의 관한 것을 기억하기 위해서이다.
사이트에 방문하면 브라우저는 서버에 요청을 보내는데,
서버는 이에 응답한다.
응답에는 모든 데이터와 내가 찾던 페이지 정보가 있고,
브라우저에 저장하고자 하는 쿠키가 있을 수 있다.
내가 브라우저에 쿠키를 저장한 후 해당 웹사이트를 방문할 때마다 브라우저는 해당 쿠키도 요청과 함께 보내게 된다.
참고로 쿠키는 도메인에 따라 제한이 된다.
유튜브가 준 쿠키는 유튜브에만 보내지게 된다. 그리고 쿠키는 유효기간이 있다.
하루, 한 달, 혹은 서버가 정한 기한에 따라,
쿠키는 인증 뿐만 아니라 여러 가지 정보를 저장할 수 있다.
웹사이트 언어설정을 바꾸면 서버는 쿠키를 주고 내가 선택한 언어를 저장한다.
따라서 다음에 해당 웹사이트에 방문할 때 쿠키는 요청과 함께 서버로 보내지고 덕분에 서버는 쿠기가 기억해 둔 언어설정의 페이지를 제공해 준다.
세션(Seesion)
http 웹사이트를 이용할 때 쓰는 프로토콜 해당 프로토콜은 stateless이다. 서버로 가는 모든 요청이 이전 요청과 독립적으로 다뤄진다는 뜻이다. 요청끼리 연결이 없다. 메모리가 없다. 요청이 끝나면 서버는 내가 누군지 잊어버리기 때문에 요청할 때마다 우리가 누군지 알려줘야 한다. 이를 하는 방법 중 하나가 세션이다.
예를 들면 A라는 유저명이 있고 로그인을 하고 싶다면 유저명, 비밀번호를 서버에 보낸다.
비밀번호가 맞다면 서버는 세션 DB에 A라는 유저를 생성한다.
해당 세션에는 별도의 ID가 있다.
해당 세션 ID는 쿠키를 통해 브라우저로 돌아오고 저장된다.
따라서 같은 웹사이트의 다른 페이지로 이동하면 브라우저는 세션 ID를 갖고 있는 쿠키를 서버에게 보낸다.
왜냐하면 쿠키는 자동으로 보내지니까 서버는 들어오는 쿠키를 보고 세션 ID와 함께 오는 쿠키를 확인한다.
아직까지는 서버는 우리가 누구인지 모른다.
세션 ID가 있는 쿠키를 지닌 요청이 있다는 것만 알 뿐이다.
해당 세션 ID를 가지고 세션 DB를 확인할 것이고,
거기서 해당 ID는 유저명 A의 것이라는 걸 알게 되며,
바로 그제야 서버는 A가 누구인지 알게 된다.
바로 그때 환영한다는 메시지를 띄울 수 있다.
해당 요청이 끝나고 다른 페이지로 이동하게 되면 이 모든 프로세스가 반복될 것이다.
기억해야 할 건 중요한 유저 정보는 모두 서버에 있다. 유저가 갖고 있는 것은 세션 ID일 뿐
보다시피 쿠키는 그저 세션 ID를 전달하기 위한 매개체 일 뿐이다.
세션을 이용해 IOS. Android 앱을 만들 수 있지만 쿠키는 사용할 수 없다. 그건 브라우저에만 있다.
바로 이경우는 토큰을 사용한다. 서버에 토큰을 보내는 것이다.
세션에 대해서 기억해야 할 것은 현재 로그인한 유저들의 모든 세션 ID를 DB에 저장해야 한다는 것이다. 즉 요청이 들어올 때마다 서버는 쿠키를 받아서 세션 ID를 보고 세션 ID와 일치하는 유저를 찾아야 하고, 그제야 다음 작업을 수행할 수 있다. 요청이 있을 때마다 DB를 찾고 해야 한다는 것이다. 즉 유저가 늘어남에 따라 DB 리소스가 더 필요한 것이다.
바로 이때 JWT가 등장한다
JWT(Json Web Token)
토큰은 그냥 이상하게 생긴 string이다. 해당 토큰을 서버에 보내고 서버는 세션 DB에서 해당 토큰과 일치하는 유저를 찾는다.
JWT는 토큰의 형식이다.
JWT로 유저 인증을 처리하면 세션 DB를 가질 필요가 없고, 서버는 유저를 인증한다고 많은 일을 하지 않아도 된다. 토큰은 그냥 이상하게 생긴 텍스트이다. 서버에서 받아서 요청할 때마다 보내야 하는 것이다. 로그인 예시를 통해 JWT와 세션의 차이점을 알아보자
유저 A가 로그인을 하려면 유저명, 비밀번호를 서버에 보내야 한다. (이때까지는 다른 것은 없음)
유저명, 비번이 맞다면 서버는 DB에 뭔가를 생성하지 않는다.
대신 서버는 유저의 ID를 가져다가 사인 알고리즘을 이용해서 사인을 한다.
그리곤 해당 사인된 정보를 string 형태로 보낸다.
eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiYWRtaW4iOnRydWV9.TJVA95 OrM7 E2 cBab30RMHrHDcEfxjoYZgeFONFh7 HgQ
JWT는 이렇게 생겼다.
보통 세션 ID 보다 훨씬 길다.
쿠키는 공간 제약이 있는데 JWT는 제약이 없어서 엄청 길어도 된다.
보다시피 동일하게 로그인을 했는데 DB를 건드리는 대신 정보를 사인하고 전달하는 것이 전부이다.
서버에 요청을 보내려면 세션 ID와 비슷하게 해당 사인된 정보 또는 토큰을 서버에 보내야 한다.
서버는 토큰을 받으면 해당 사인이 유효한지 체크하고,
이는 토큰을 조작했는지 체크하는 것이다.
토큰이 유효하다면 서버는 우리를 유저로 인증할 것이다.
바로 세션과 JWT의 가장 큰 차이점이다.
세션에서는 그냥 세션 ID만 주면 된다. 세션에 대한 정보는 세션 DB에 저장되어 있다. 페이지를 요청하면 서버는 세션 ID를 DB에서 찾으면 된다.
JWT에서는 서버는 유저를 인증하는데 필요한 정보를 토큰에 저장한다. 그리고서는 해당 토큰을 우리에게 부여한다.
페이지를 요청하면 서버는 해당 토큰이 유효한지만 검증하면 된다. DB를 거칠 필요가 없다.
염두할 것은 JWT는 암호화되지 않았다. 암호화 되었다면 아무도 읽을 수 없고, 이해할 수 없다.
누구나 열어서 해당 콘텐츠를 볼 수 있다는 것이다. 비밀정보를 JWT 안에 둬서는 안 된다.
핵심은 토큰을 사인하고 이를 통해 유효한지 검증한다는 것이다.
세션 vs JWT 장단점
세션을 사용하면 서버는 로그인된 유저의 정보를 저장한다. 해당 정보를 이용하면 새로운 기능들을 추가할 수 있게 된다. 예를 들면 특정 유저를 쫓아내고 싶을 때 그때 그냥 세션을 삭제해 버리면 된다. 혹은 인스타그램처럼 할 수 있다. 로그인된 모든 디바이스를 보여주는데 원하지 않는 디바이스에서 강제 로그아웃을 할 수 있다.
아니면 넷플릭스처럼 계정 공유 숫자를 제한할 수 있고, 현재 로그인을 몇 명이 했고 시청하는지 알 수 있다. 이 모든 것은 서버가 누가 로그인 했는지 저장했고, 세션 DB가 있기 때문이다.
염두해야 할 것은 이렇게 다 알고 싶다면 DB를 구매하고 유지해야 한다. 게다가 유저가 늘어나면 늘어날수록 DB도 커져야 한다. 이를 위한 DB로는 redis를 주로 사용한다. 해당 목적을 수행하기 위한 빠르고 저렴한 DB라고 한다.
JWT를 사용하면 생성된 토큰을 추적하지 않는다. 서버가 아는 것은 토큰이 유효한가 여부일 뿐이다. JWT에선 DB를 따로 살 필요는 없다. 하지만 동시에 로그인된 디바이스에 강제 로그아웃기능을 할 수 없다. 해당 토큰이 만료되기 전까지는 유효 하기 때문이다.
그렇다고 JWT가 별로인 것은 아니다 데이터를 사인하고 유저에게 보내고 해당 데이터를 돌려받을 때 유효성을 검증할 수 있다. DB 없이 모든 것이 가능하다. 이전에 코로나 QR코드는 JWT가 들어가 있다.
보다시피 JWT는 사용 사례가 많다.
그중 하나가 세션이나 DB 없이 유저를 인증하는 것이다.
JWT 인증의 제약만 잘 알아두면 된다.
하지만 서비스가 커지고 유저 계정을 좀 더 관리를 잘하고 싶다면 세션으로 사용하는 것이 좋을까 싶다.
'Network' 카테고리의 다른 글
REST, REST API, RESTful (1) | 2023.12.15 |
---|