인증(Authentication)과 인가(Authorization)의 Story
나는 회사에 출근을 한다.. 굳게 닫힌 문은 나의 신원확인을 기다리고 있었다 삑! 나의 신원 확인이 완료되었다 그리고 마침내 문은 환영한다는 듯이 문을 활짝 열어주었다 난 오늘도 내가 다니는 회사로 출근을 했다
-인증(Authentication)-
위에서 보았듯이 나의 신원을 확인하는것이 인증이다.
내가 이곳에 다니는 사람이라는 증명, 누군가에겐 무겁겠지만 누군가에겐 일상은 그 행위가 인증이라고 알려준다.
회사에 출근한 나는 자연스럽게 탕비실에 가서 커피를 타 마시며 하루를 시작한다. 물론 그전에 화장실도 빼먹지 않았다. 출근 후 화장실은 나에겐 루틴이다 그리고 내 자리로 돌아와 컴퓨터를 켰다. 아! 내가 잊은 것이 있었다. 나는 서류를 들고 사장님의 방으로 들어가려고 했다. 그러자 문 앞의 비서가 나를 막는다 "무슨 일로 오셨어요? 예약은 하셨나요?"..... " 안 했습니다 "..... "그럼 다음에 다시 오세요 ㅎㅎ"
-인가(Authorization)-
보았듯이 우리는 회사에 들어가는것은 우리가 회사의 소속되어 있는 직원이기 때문에 가능하다
하지만 회사에서 일하는 사람들 간에도 직급의 격차가 있었고 나에게 허가된 장소는 제한되어 있다. 이것이 인가이다.
우리는 클라이언트와 서버로 이루어진 곳에서 HTTP를 통해 소통을 한다는 것을 알고 있다.
여담으로 HTTP는 Stateless(무상태성)을 기반으로 요청을 처리한다.
※ 요청 하나하나에 연관관계를 짓지 않는 것을 말한다.
기본적인 데이터의 흐름을 파악해 보자
가정을 해보자
- 클라이언트는 회원가입을 통해 로그인을 하고 그 정보를 DB에 저장해 둔 뒤 인증이 필요할 때 DB에서 값을 가져와 정보가 맞다면 로그인을 하는 것이 일반적인 과정이다.
- 인증을 받고 유저는 글을 쓰거나 댓글을 작성하는 등 다양한 행위를 할 것이다 하지만 그는 행위 하나하나에 모든 인증을 거쳐야 한다. 계속된 인증에 사람은 지치게 되어있다
- 그래서 있는 것이 브라우저의 스토리지이다. 그곳에 본인의 ID를 저장하고 다시 들어갈 때 굳이 DB까지 가지 않고 즉, 인증을 다시 거치지 않고 들어갈 수 있는 것이다.
● 단점 1. 보안의 취약점
하지만 이는 굉장히 안 좋은 단점이 있다. 바로 보안이 굉장히 취약하다는 것이다.
이 단점을 보안하기 위해 다른 방법이 있다.
해결방법 = 임의의 문자 전달
DB에서 정보를 받고 다시 줄 때 받았던 정보를 그대로 주는 것이 아닌 Session이라는 것을 통해 정보를 가린다는 것이다.
세션은 인증된 사용자의 이름(ID)과 랜덤 한 문자의 조합으로 만들어 클라이언트에게 보내고 클라이언트는 Session의 Key값과 함께 정보를 저장한다. 이로써 자신의 정보의 모든 것이 클라이언트 서버에 저장되는 것이 아닌 서버에서만 확인이 가능한 ID가 생기는 것이다.
● 단점 2. 세션의 흐름의 문제
하지만 이것 또한 문제점이 발생한다. 우린 서버를 한 개만 사용하는 것이 아니라는 것이다.
클라이언트는 DB에서 준 세션 정보를 저장할 것이다. 여기까지는 문제가 없다 하지만 서버에서 문제가 생긴다.
- 두 개 이상의 서버가 생기는 바람에 클라이언트는 무작위 서버에게 자신의 세션 정보를 인증받을 테고 처음에 세션을 받은 서버가 아니고서야 다른 서버에서 세션값을 확인할 방도가 없는 것이다.
해결 방법 = Session 스토리지
세션 스토리지는 모든 서버에서 관리하는 세션을 한 곳에 몰아둔 곳이다.
그곳을 따로 관리해서 세션의 정보를 모든 서버가 알 수 있게 하는 것이다
● 단점 3. 클라이언트의 증가
이젠 당연하다 문제가 생겼다.
세션 스토리지가 버티지를 못한다는 것이다. 이용자의 수가 증가하면서 서버도 증설하는데 그 많은 세션을 관리할 스토리지도 정상일 수 없는 것이다
우리는 앞서 통신함에 있어 Stateless(무상태성)을 지향하고 있었다. 하지만 우리가 지금까지 한 것은 계속해서 정보를 저장하고 있어야 하기 때문에 State가 되는 것이다 그래서 이 두 개의 패러다임을 부술 필요가 있다고 생각한 것이다.
그래서 클라이언트도 서버도 DB도 아닌 흐름 자체에 맡겨보기로 한 것이다.이 흐름안에 유저의 상태를 담아보기로 한것이다. 이러한 인증방법이 바로 TOKEN을 활용한 인증방법이다 이로써 JWT가 나타난 것이다
해결 방법 = JWT(JSON WEB TOKEN)의 사용
JWT를 간단하게 말하자면 Security를 통해 JWT를 만들고 인증과정을 거친다 하지만 JWT자체의 보안성은 굉장히 취약하다 그래서 JWT에는 사용자의 민감한 정보는 담지 않는다. 그리고 Security내부에서 잘 관리를 해야 하는 것이다.
활용
평범한 과정처럼 사용자 정보가 담긴 로그인을 한다. 그러면 서버는 Security를 통해 JWT를 만들어내고 그것을 클라이언트에게 보내 스토리지에 저장한다. 그리고 사용자가 또다시 로그인을 할 때 서버가 자체의 security를 이용해 검사를 한다. 검사는 사용자의 간단한 정보를 토대로 한다. 이름, 토큰의 만료시기, 권한 등의 기준을 검사하여 확인하는 것이다. 아까 말했다시피 토큰 자체에 민감한 정보(비밀번호)는 담지 않는다
◐ 장점
- 아까는 큰 저장소가 필요했지만 JWT는 토큰이기에 각자 서버가 가지고 있는 security로 해독을 하여 인증할 수 있다
- 서버가 몇 대가 되던 security를 사용하는 것은 변함없기 때문에 서버의 확장이 용이하다
◑ 단점
- 초반에 나왔던 해커의 침입에 대한 불안요소가 있다. 토큰자체는 해독하기가 쉽다
- 이를 막기 위해 만료기한이라는 것을 사용한다.
하지만 이는 사용자 또한 불편함을 같이 겪기 때문에 나온 대안 Refresh Token이라는 것이 있다. - 서버는 토큰을 만들어낼 때 Access Token과 Refresh Token을 한 번에 만들어낸다. 이때 저장소에서는 Access는 버리고 Refresh만 저장하게 된다.
- 그리고 이 두 개의 토큰을 클라이언트에게 보내고 클라이언트는 두개다 저장한다.
- 클라이언트는 Access를 통해 로그인을 하다가 만료가 되면 클라이언트는 두개의 토큰을 함께 서버에게 보내고 서버는 그중 Refresh토큰을 저장소와 있는 토큰과 비교 후 맞다면 새로운 Access토큰을 보내 다시 저장하고 사용하는 것이다.
- 이를 막기 위해 만료기한이라는 것을 사용한다.
'Spring' 카테고리의 다른 글
IoC 컨테이너 (0) | 2023.03.22 |
---|---|
Spring Security - Exception (0) | 2023.03.22 |
DAO 와 DTO(VO) 는 뭘까? (0) | 2023.03.22 |
어노테이션과 어노테이션의 종류 (0) | 2023.03.21 |
websecurityconfigureradapter가 deprecated되었다 (0) | 2023.03.21 |