앞서 인증(Authentication)은 로그인 하는거고 인가(Authorization)는 로그인 되면 정보를 인증한 사람한테 푸는것이다.
우리는 인터넷을 사용할때 로그인을한뒤에 여러 정보들을 요청하고 받게된다. 네이버 로그인하고 메일을 확인도하고 카페도 이용을하고 뉴스도 보곤한다. 그런데 이게 자동으로 그냥 되는게 아니라는건 우리의 눈물나는 실습들이 증명해 왔을 것이다. 오늘은 뭐가 어떻게 돌아가고 있었는지 개념을 챙겨보는 시간을 가질까 한다.
쿠키는 사용자 설정을 브라우저에 저장하면 다음번에 서버로부터 정보를 받을때 서버는 쿠키 설정을 기반으로 맞춤 정보를 보내게 된다.
예를들어 크롬에서 화면을 어두운테마를 설정하면 내컴퓨터에 쿠키로 저장이되며 서버에서는 다음에 내가 정보를 요청할때 거기에 맞춰서 화면 설정을 보내는 것이다. 혹은 구글에 언어 설정을 하면 쿠키에 내가 어떤 언어로 설정했는지도 기록되게 된다. 혹은 오늘 하루 이창을 보지 않겠습니다. 같은 체크박스들 말이다.
추가로 캐시는 임시보관이라고 생각하면 된다. 우리가 네이버에 접속할때 우리 컴퓨터나 서버에 캐시로 저장을 하게 되면 네이버에 홈페이지에 있는 수많은 사진들이나 css 혹은 JS정보들을 임시보관 해서 또 방문할때 임시보관한 곳에서 빠르게 꺼내게 된다.
다음으로 세션의 흐름에 대해 설명하겠다 여기서 3가지를 먼저 기억해야한다
서버,DB,쿠키
사용자가 로그인을 요청하면 서버는 누가 누군지 모른다. 로그인 요청을 했으니 아이디랑 비번을 보낼텐데 서버가 이걸 DB랑 확인을 하고 맞으면. DB에 사용자를 위한 세션객체를 만들어 버린다.
그럼 Session DB가 Session id를 저장 할수 있는 쿠키를 만들어서 사용자한테 보내버린다.
그럼 사용자는 쿠키에 들어있는 Session Id를 가지게 되는데 이 쿠키를 사용자가 다시 서버로 보낸다. 그런데 서버는 멍청해서 뭐하나 처리하면 까먹는데 쿠키를 받은 서버는 이게 뭔지 모른다. 그저 아… 쿠키가 나한테 왔네 한다. 그래서 세션DB한테 이 쿠키 누구꺼야? 라고 물어보는데 DB가 아 이거 사용자 누구꺼야 라고 말해주면 서버가 아하! 하고 사용자가 원하는 정보를 뿌리는 것이다.
정리하면)
1.로그인한다.
2.서버가 아디/비번 맞는지 DB랑 체크
3.맞으면 DB가 세션ID를 발급해서 쿠키에 저장하고 이 쿠키 정보를 DB에 저장
4.DB가 서버를 통해 사용자 한테 세션 ID들어있는 쿠키를 준다.
5.사용자가 받고 다시 서버에 쿠키전달
6.서버가 DB한테 요청해서 이 쿠키의 주인의 정보를 서버한테 내놓으라고 함
7.서버가 사용자한테 원하는 화면 띄워줌
8.우리가 로그인 하지 않아도 위의 행동을 무한반복.
이 쿠키로 우리는 로그인하고 네이버 뉴스나 지식인, 카페 같은 다른 페이지로 이동할때 마다 계속해서 로그인 하지 않아도 되는것이다. 왜냐하면 세션이 이 과정들을 알아서 반복해 주기 때문이다.
그런 이유로 우리가 인터넷설정 들어가서 쿠키를 지워버리면 로그인도 같이 풀리게 되는 것이다.
그런데 이게 좋은데 단점이 페이지 뭐 클릭할때마다 DB를 계속 다시 뒤져야 하니깐 사용자가 겁나 많아지만 무리가 간다. 그래서 서버의 자원이 많이 소요되는 것이였다. 이러다가 서버 터지는거고.
이래서 JWT가 나왔다.
이녀석은 토큰을 이용하는 방식인데 세션이랑 조금 다르다.
JWT가 뭔지 소개부터 하면 Json Web Token 이라는 말인데 한마디로 Json 방식으로된 웹 토큰이다.아래 화면으로 보자.
이녀석은 base64로 인코딩 하게 된다. https://jwt.io/ 여기가 공홈인데 구조를 파악해 볼수 있다.
위의 사진 보면 점으로 3덩이가 나뉜걸을 볼수가 있다.
각각 Header, Payload, Signature 이다.
Header는 어떤 토큰방식으로 인코딩 했는지 보여주는 부분이다. Json 객체를 인코딩하면 JWT가 된다.
Payload에는 서버에서 활용할 수 있는 사용자의 정보를 담아주는데. 어떤 정보에 접근 가능한지에 대한 권한을 담을 수도 있고, 사용자의 이름 등 필요한 데이터를 담을 수 있다.
Signature는 Header, Payload를 섞어서 만들 암호키를 인증 하는데 쓰이게 된다.
여기까지 JWT가 뭐고 구조가 뭔지 설명이였다.
아이디랑 비번을 확인하는건 같은데 DB에 아무것도 만들지 않는다 쿠키 이런것도 필요가 없다. 서버가 우리가 맞다고 승인을한 토큰 이라는것을 주는데 이걸 가지고 계속 인가를 하는것이다. 우리가 이후에 페이지 요청을 하면 서버는 우리가 보낸 토큰이 맞나 틀리나만 독단적으로 판단하고 그냥 가져가세요~ 하고 냉장고 뒤지듯이 DB에서 꺼내 줘버린다. (우리가 들고 다니는 신분증 맞으면 그냥 술담배 주는것 처럼)
여기까지 보면 엄청 좋아 보이는데 단점이 있다. 바로 누가 토큰 가져가면 답도 없어지는 상황이라는거다.(아래 설명)
(여담인데 토론토 TTC는 거의 일년? 전까지만해도 토큰도 썻음 필자도 학교다닐때 토큰 사용해서 위의 사진이 익숙하다...)
먼저 세션의 장점을 볼까?
누가 내 구글 계정에 로그인을 한적이 있다. 그런데 구글에 모든기기에서 로그아웃 이라는 기능을 제공하는데 이게 DB에 있는 내 세션을 날려버리는 것이다. 그럼 쿠키도 다 쓸모 없어지기에 다시 로그인을 해줘야 한다. 이거 진짜 좋다. 토큰..? 어림도 없지. 뿐만아니라 넷플릭스 볼때도 여러명이서 볼때 1번유저, 2번유저, 3번유저 등등 여러명이 로그인 한것도 볼수 있고 하는데 이게다 DB에 저장해 놓기 때문에 가능한거다.
세션의 단점은 위의 설명처럼 자원을 많이 잡아 먹는다...
JWT의 장점을 보자.
DB가 개입을 안하니 속도와 자원활용이 좋겠다. 또한 토큰이 신분증 같은건데 코로나 백신 QR로 가게 들어갈때 QR코드가 토큰 구조다. 그냥 바로 쓸수 있는거지. 또한 스택에서 본건데 디코 2단계 인증을 JWT 방식으로 한다고 한다. 생각해보니 나도 옛날에 2단계 인증으로 스팀가드를 만든적이 있는데 인증코드를 이메일로 보내주고 잃어버리면 큰일난다고 심하게 경고를 받은 기억이 있다. 최근에 스팀가드를 들어가보니 인증코드를 15초 마다 바꾸는걸 봤다. 이런게 JWT다. 신기하지 않은가?
JWT의 단점을 보자.
이녀석은 혼자 못사용한다. 이유는 보안에 취약하다. 내가 친구의 백신 QR코드 스샷찍어서 그걸로 가게에 들어가 보자. 가능하다. 사람이야 신분증 보여주면 이거 본인 맞아요 라고 물어나 보지 컴퓨터는 어림도 없다 그냥 보여주면 맞는거다. 그런데 JWT로 로그인 기능을 구현을 할때가 있는데 계속 로그인 상태를 유지하기 위해서 Access토큰이랑 Refresh 토큰 두개를 만들어 버린다. Access 토큰으로 서버랑 정보를 주고 받다가 Access토큰을 서버가 삭제해 버리고 사용자가 가지고 있는 Refresh 토큰으로 Access 토큰을 또 만들어 버린다. 그래서 Access 토큰은 해킹 위험때문에 사용시간이 짧고 Refresh 토큰은 사용기간이 길다.
JWT가 취약하다 보니 혼자는 안쓰인다. 개발자들은 세션에서 JWT로 넘어가다 다시 세션으로 돌아왔다고 한다. 보통은 세션이랑 JWT랑 같이 섞어서 사용하고 아니면 작은 프로그램이면 JWT만 사용할수는 있을것 같다.
'스프링 Security > 정리' 카테고리의 다른 글
(스프링 Security)HTTPS (0) | 2023.01.13 |
---|