인증과 인가가 어떻게 이뤄지고 어떤 방식이 있는지 알지 못했을 때의 일이다.
세션 기반 로그인을 구현하는데 로그인에 분명 성공했다고 했는데, 로그인을 다시 할 수 있었던 적이 있었다. 지금 생각하면 아 세션유지가 안된거구나 라고 생각 할 수 있었는데 그 때 당시에는 굉장히 골머리를 앓았던 기억이 있다.
해결하기 위해서 공부 했던 것을 좀 더 보기 좋게 정리해서 오래 기억하도록 기록하겠다.
공부를 하면서 이해해 도움을 받았던 루피님 과 토니님 의 인증 인가의 강의를 토대로 작성하였습니다.
우리는 어렴풋이 인증과 인가가 뭔지는 알고는 있다.
신원 확인 & 신원이 확인된 사람의 접근 허용
좀 더 개발자 답게 말하자면
인증
보호된 리소스에 접근하는것을 허용하기 이전에 등록된 유저의 신원을 입증(Validating)하는 과정.
인가
요청된 리소스에 접근할 수 있는 권한이 있는 인증된 유저인지 입증하는 과정
위에서 말한거와 같이 인가는 항상 인증 다음에 온다.
웹에서의 인증 / 인가
인증과 인가를 효과적으로 이해하기 위해서는 사전지식이 필요한데,
서버와 클라이언트 그리고 HTTP 에 대해서 알고 있어야 한다.(특히 Statless 속성)
만약 우리가 naver에 로그인을 한다고 가정해보자.
naver DB에 회원가입된 정보가 이미 존재하고, 이상황에서 로그인을 하면 어떻게 하면될까?
요청이 들어온 url을 Base64라는 인코더를 이용해서 인코딩을 한 후에 http request를 전달 (이 부분은 클라이언트. 즉, 브라우저가 한다)
url에서 로그인에 관한 부분을 파싱한 후에 인코더를 통해서 인코딩한 문자열을 브라우저가 가지고 있다
이를 request header의 Authorization에 넣어서 보내주는 개념.
이렇게 브라우저가 http를 통해 서버로 날려주면 서버에서는 DB 체킹을하고 일치여부를 판단한다.
만약 로그인한 사용자가 글을 다쓰고, 수정하고 싶다면? 또 인증 요청이 들어가야한다.
그렇다.
매번 인증을 한다.
이러한 점을 해결하기 위해서 브라우저의 힘들 빌리게된다.(정확하게는 브라우저에있는 스토리지의 힘)
스토리지는
있는데 먼저 쿠키를 설명하겠다.
쿠키에 간단하게 사용자 아이디, 비밀번호를 집어넣는다. 그리고 사용자가 인증이 필요한 요청을 할때 같이 준다. 그러면 확인을 하고 원하는 자원을 받게된다.
1. Cookie에 사용자의 ID, PW를 넣는고 인증이 필요한 요청을 할 때 Cookie도 같이 Server에 보내준다.
2. Server는 DB에 쿠키에 담은 정보를 확인 요청하게 된다.
3. DB는 Server가 요청한 DB 값이 있는지 확인 후 callback 해준다.
4. Server는 다시 client에 callback 해준다. 그리고 사용자는 원하는 자원을 얻을 수 있다.
(사용자의 아이디와 비밀번호를 그대로 노출하기 때문에 보안에 매우 취약하다.)
이러한 단점을 해결하기 위해서 Session을 활용하여 Server에 도움을 요청하게 된다.
방식은 동일하다.
그렇다면 단점이 존재 안하나? 그건 아니다.
빨간 점선은 Load Balancer 이다.
서비스가 잘 돼서 서버를 여러 개 두게 되면 로드 밸런서도 생기게 된다.
Load Balancer 란? : 서버에 가해지는 트래픽을 여러 대의 서버에서 균등하게 분산시켜주는 역할.
한 번 인증돼서 SESSIONID를 받게 되면 다음 요청 땐 Session으로만 이용해서 요청하게 된다.
즉, 이젠 DB까지 확인하지 않고 Server에서 Session을 확인하여 처리할 수 있게 됐다는 뜻이다.
다른 서버에 인증 요청을 보내면 어떻게 될까?
문제 해결 - Session DB
Session Storage( 세션 DB) 통해서 SessionID 요청을 한 DB에 요청하여 해결할 수 있다.
그러나 또 다른 문제가 발생한다.
우리는 클라이언트, 서버 ,Session저장소 모두 사용자의 상태관리를 할 수 있게 해봤다.그랬더니 문제가 발생하였다.
그 이유는 Client와 Server가 서로 통신할 때 사용하는 http와 Server 자체가 지향하는 REST API가 무상태성(Stateless)을 기초로 하기 때문이다.
그런데 실제로 인증과 인가를 진행할때 사용자의 정보 , 상태를 3군데 모두 가지고 있었다. 그 말은 상태성을 가지고 있었다는 것이다.
패러다임이 충돌을 하기 때문에 문제가 생긴것이다. 이것을 해소해야지 문제가 해결된다.
처음으로 돌아와서...
우리는 위에서 사용자의 상태를 클라이언트와 서버 둘다 모두에게 맡겨봤었다.
이제 요청과 응답안에 담아 보기로 했다.
그래서 나오게 된것이
이다.
JWT 로직
그렇다면 단점은 없는가?
Access Token이 탈취 당한다면 해커는 사용자와 똑같은 지위를 갖게 된다.
Token 만료기한을 설정해 놓으면 만료기간 이후 해커뿐만 아니라 사용자도 사용할수 없어서 불편할 수 있다.
그래서 나온 개념이 ?
토큰 관리를 해야 하며, 결국 토큰도 탈취당할 수 있다. 따라서 보안에 꾸준히 신경을 써야한다.
는 다음 포스팅에서 이어서 하도록 하겠다.