로그인기능을 구현한는 것도 어렵지만 무엇보다 로그인 상태를 '유지'하는거도 만만치 않게 어려운 일이다.
예로 들어 naver에 로그인을 했을 때 메일함을 들어가고 나올때, 보낸 메일함과 받은 메일함을 들어갔다 나올때 마다
로그인을 다시 하면 사용자들은 상당히 불편할 것이다.
그래서 서버에서 현재 사용자가 로그인을 했는지 안했는지를 알수 있어야 로그인 상태가 유지가 된다.
인증(Authentication). : 로그인
==> 내가 이 사이트에 가입된 회원임을 즉, 특정 서비스에 일정 권한이 주어진 사용자임을 아이디랑 비밀번호를 통해서 인증을 받는것
인가(Authorization)
==> 한번 인증을 받은 사용자가 이후 서비스의 여러기능을 사용할 때 매번 로그인 되어있음을 알아보고 허가 해주는것.
예) sns에 한번 로그인(인증)을 한뒤 내 계정의 사용자으로'만' 할 수 있는 활동을 할 때 sns 서비스가 내가 로그인됨을 인지하는것
셰션
사용자가 로그인에 성공하면 서버는 '세션 표딱지'란걸 출력한다.
그리고 그것의 반은 브라우저에 보내고 반은 메모리에 넣어 놓는다. (상황에 따라 하드디스크에 넣거나 데이터베이스에 넣는다)
그러면 브라우저는 이 딱지를 Seesion ID란 이름의 쿠키(브라우저에 저장되는 정보)로 저장하고
브라우저는 앞으로 해당 사이트에 요청을 보낼때 마다 이 표를 실어서 요청을 보낸다.
그리고 브라우저에서 온 반쪽 세션을 서버에서 비교 대조 한뒤 맞으면 인가를 해주는것이다.
세션의 허점 : 메모리상에 저장할 경우 서버가 꺼지는 상황이나 에러가 발생하면 휘발성인 메모리는 세션이 모두 날아가서
모든 사용자들이 로그인을 다시 해야한다. 또한 사용자가 여려명이 동시 방문하면 메모리가 부족해 진다.
또한 하드디스크나 데이터베이스에 저장할 경우 속도도 너무 느려진다.
보통 레디스나 memcashed같은 메모리형 데이터베이스 서버에 두기도 하지만 첫 허점과 같이 에러나 서버가 꺼지면 모두 날아간다.
더군다나 서버여러대를 거쳐 진행되는 서비스일 경우 로직이 꼬이는불상사도 일어난다.
이 모든 허점을 보안하지 위해서 나온게 JWT이다.
참고로 브라우저가 아닌 ios나 안드로이드같은 어플리케이션에는 쿠키가 없어 jwt를 사용해야 한다.
JWT
JWT는 인가에 관련된 개념이다.
jwt는 로그인을 하면 반쪽짜리 표를 주는것이 아니라 전체(토큰)를 다 보내준다.
즉, 서버가 무언가를 저장 하지 않는다.
eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyfQ.SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5c
그 토큰은 인코딩 또는 암호화된 3가지 데이터를 이어 붙인 형태이다.
빨간색(header), 보라색(payload), 파란색(verify signature)로 구분이 된다.
payload를 디코딩해보면 json 형식으로 여러 정보들이 있다.
이 토큰들이 누가 누구에게 발급을 했는지, 언제까지 유효한지,
서비스가 사용자에게 이 토큰을 통해 공개하기 원하는 내용( 사용자의 닉네임, 관리자 여부 등등)
하지만 간단히 bas64rul로 인코딩한 방식이기에 변조와 조작의 가능성이 높은 우려가 있다.
이를 위해 헤더와 시그니처가 있다.
header에는 타입과 알고리즘의 종류 2가지가 들어간다 타입은 늘 JWT가 들어며
알고리즘에는 3번 시그니처(서명값)을 만드는데 사용될
알고리즘이 지정된다.
그리고 '헤더'와 '페이로드' 그리고 '서버에서 감춰놓은 비밀키' 이 셋을 암호화 알고리즘에 넣고 돌리면 3번 시그니처(서명값)이 나온다.
또한 암호화 알고리즘은 한쪽 방향으로는 계산이 돼도 반대쪽으로는 안되서 서버만 알고있는 비밀값을 알 방법이 없어 안전하다.
즉, 요청이 오면 클라이언트에서 보낸 토큰에서 헤더와 페이로드를 뽑아 서버에서 가지고 있는 비밀키를 조합해서
클라이언트에서온 시그니처(서명값)과 같은지 확인해서 인가를 판단한다.
즉 stateless 하다. 반대로 세션은 stateful하다.
하지만 세션을 대체하기에 jwt도 결점이 있다.
세션처럼 stateful해서 모든 사용자들의 상태를 기억하고 있다는건 구현하기 부담되고 고려사항도 많지만,
이게 되기만 하면 기억하는 대상의 상태들을 언제든 제어할 수 있다는 의미다.
예를 들어
1. 한 기기에서만 로그인 가능한 서비스를 만들려는 경우 pc에서 로그인한 상태의 어떤 사용자가 핸드폰에서 또 로그인하면
pc에서 로그아웃 되도록 기존 세션을 종료할 수 있는 것이다.
2. 특정 유저 쫒아내기
3. 로그인된 모든 디바이스를 보여주는데 원치 않는 디바이스에서 강제로 로그아웃을 할 수 있다.
4. 계정 공유숫자를 체크할 수 있다.
즉, 정말 간단히 요약을 하자면 간단한 서비스에는 JWT를
서비스와 사용자가 커져서 많은 기능과 컨트롤을 해야할 경우 세션을 이용하면 될것같다.
'모카 스터디 > 웹 지식' 카테고리의 다른 글
YouTube API Key 획득 및 사용법 (0) | 2023.08.13 |
---|---|
프론트엔드 CORS 개념 정리 (0) | 2023.08.06 |
백엔드 로드맵 (0) | 2023.07.16 |
리눅스 & 서버 [생활코딩] (0) | 2023.07.15 |
google 로그인 [생활코딩] NO backend (0) | 2023.07.15 |