오늘은 Session과 JWT에 대해 학습을 해보겠다! 🔥🔥🔥
사실 면접을 준비하면서 Login에 대한 질문을 대비하기 위해 이렇게 게시글을 작성하고 있다!! 지난 JB 프로젝트에서 Login에 대한 허점이 얼마나 있었는지를 알 수 있었다.. 다시 이를 학습해보니 회원분들의 개인정보에 미안한 마음이 든다..🥲 이제 이 부분을 완벽하게 숙지하고 다음 프로젝트에서는 좀더 보완적으로 완벽한 Login 로직을 개발할 수 있을 것이다..!
인증과 인가의 차이를 먼저 알아야한다. 예시를 들어설명할 수 있다.
놀이공원에서 우리가 입장권을 사서 입구에서 입장권을 보여주고 입장팔찌를 받은 후 놀이공원에 입장한다.
이는 인증(Authentication)!! 이다.
그리고 놀이기구를 탈 때마다 입장팔찌를 보여주는 것이
인가(Authorization)이다.
즉, 웹 사이트에 들어가 어떤 입장권을 받는 과정이 인증
받은 입장권을 어떤 요청마다 확인하는 것이 인가이다.
자 그럼 왜 Session, JWT가 Login 인증 방식인지 알 수 있다.
먼저, 로그인을 할때 어떤 과정을 거치는지 생각해보자
User는 ID와 PW를 입력한다. 만약 이런 ID, PW와 같은 민감한 정보를 바로 DB에 저장하고 이를 비교한다면 보안상으로 문제가 없을까?(프로젝트에서 실제 그렇게 했던 1인;;)
그럼 어떻게 로그인을 시도할 때 보안을 높일 수 있을까?
- HTTPS 통신: HTTPS를 사용하면 데이터가 암호화되어 전송되므로 중간에 정보가 노출되는 것을 방지할 수 있다.
- 해싱된 ID,PW 저장
데이터 베이스에 바로 ID,PW를 저장하는 것이 아닌 알고리즘화해서 암호화된 정보를 저장하고 이를 비교할 때도 해싱하여 ID,PW를 비교할 수 있어야한다.
자, 그럼 놀이공원에서 입장팔찌를 채워주는 거 같은 인증방식을 한번알아보자
Session은 기본적으로 Session ID라는 것을 생성한다.(Login 정보가 일치하면) 그 후 클라이언트에게 SessionID를 전달하고 브라우저는 이 SessionID를 보통 쿠키에저장한다. 그리고 서버는 이 Session ID를 메모리 또는 DB에 저장한다. 사용자가 로그인하고 어떤 인가처리를 요구할 때 해당 메모리나 DB의 SessionID와 비교한다.
그럼 이 방식은?? 사용자의 인가처리가 필요할 때마다 메모리나 DB를 뒤져야 하기때문에 서버에 부담이 되고 너무 많은 요청이 있을 때는 서버 과부하를 일으킬 수 있다.(그렇기 때문이 Load balancing이 중요) 그럼 서버에 저장하지 않고 Login 인증,인가를 할 수 있는 방법은 없을까??
JWT는 로그인에 성공하면 JWT Token을 발행해 클라이언트에게 전달해준다. 이 Token에는 사용자에 대한 id나 유효기간등에 대한 정보를 암호화하여 인코딩하여 저장한다. 그리고 인가를 할 때마다 JWT는 유효기간에 대한 검증만 거친 후 통과시켜준다. DB나 메모리가 필요없기 때문에 속도는 굉장히 빠르다.
대신 개인정보가 Token에 담겨있기 때문에 암호화 되어 있더라도 해커가 디코딩하여 Token을 탈취할 수 있고 또, JWT Token은 서버가 기억하고 있지 않고 유효한지만 확인하기 때문에 JWT를 특정할 수 없다.
그렇기 때문에 토큰이 탈취당해도 이를 막을 방법이 없다. 하지만 대규모의 사용자가 사용하는 웹 사이트라면 JWT의 빠른 인가방식은 장점이 될 수 밖에 없다.
그렇기 때문에 현재 JWT방식은 Access Token과 Refresh Token으로 유효기간에 대한 단점을 보완하고있다. Access Token은 유효기간을 약 5일정도로 짧게 잡고 Refresh Token의 유효기간은 약 2주로 잡는다. 그럼 서버가 인가를 원할 때는 Access Token을 확인하고 만약 Acccess Token의 유효기간이 만료되었다면 Refresh Token을 확인하여 Access Token을 발급해준다.
이렇게 되면 탈취를 당하더라도 해커가 사용할 수 있는 Token의 유효기간이 짧아 피해를 최소화할 수 있다.