즉, 사용자가 어떤 활동을 할때 -> 서버는 이게 로그인 된 사용자인지 (인증과정을 거친) 확인 -> 그에 따라서 로그인을 해야만 할 수 있는 작업에 대한 권한을 부여해줌. 인증이 안됐다면 당연히 거부.
- 만약 DB에서 사용자의 계정에 따른 해시값을 꺼내오고 알고리즘으로 계산해서 암호가 일치하는지 확인하는 방식을 사용할 경우... -> DB에서 뭘 꺼내온다는것 자체가 고비용.
- 요청마다 id와 pw를 실어서 보내면.. -> 당연히 보안에 매우 취약함.
- 그래서 사람들이 세션방식과 토큰 방식을 고민하게 되었다.
이 1-6번까지의 단계. 즉 세션 아이디를 사용해서 어떤 사용자가 서버에 로그인 되어있는것이 지속되는 상태
를 세션
이라고 한다.
즉 서버가 복잡한 구성과 환경에서는, 어떤 상태를 기억해야한다는 것이 굉장히 복잡
하다.
그래서 토큰 방식인 JWT(Json Web Token) 을 고민하게 되었다!
사용자가 로그인에 성공하면 토큰이라는 표를 출력해준다.
앞서 세션과는 달리, 반으로 자르지 않고 통째로 브라우저에만 넘겨준다. 즉 서버는 기억하고 있는게 하나도 없음!
토큰을 들여다보면, 중간에 마침표로 3단계로 구분히 됨을 볼 수 있다.
xxxx.yyyy.zzzz
이것은 크게 (1)Header , (2)Payload, (3) Signature 로 구성되어있고 base24 암호화 방식을 사용하고 있다.
(1) Header - 토큰의 정보
(2) Payload - 인가에 필요한 정보가 담겨 있다.
- 페이로드를 디코딩 해보면 Json 형식으로 여러개 나누어진다.
- 이 부분은 유효기간, 사용자 정보 등 이 담겨있고 이것을 클레임
이라고 한다.
- 즉 Payload 는 클레임
의 집합!
(3) Signature - 특수한 서명값
즉 서버로 토큰을 보내면, 클레임들만 확인해서 필요한 인가를 처리하면 되므로 서버에서 일일이 DB에서 안뒤져봐도 된다.
1-5번 방식을 통해 세션의 단점을 보완할 수 있다!
-> 그래서 1,3번 파트인 Header와 Signature를 사용합니다.
위에서 간단히만 설명했던 (1),(3)번 파트를 이제 자세히 정리하자면..
(1) Header - 토큰의 정보를 담고 있음.
- type : 토큰의 타입을 지정. JWT!
- alg : (3)번의 서명값을 검증할 해싱 알고리즘 지정.
대표적으로 HMAC SHA256와 RSA가 있다.
(3) Signature - 특수한 서명값.
- (1)번과 (2)번을 합친 값을 비밀키로 해쉬 하여 생성한 값
- 서버만 비밀키를 알고있다!
결론 : (1)+(2)값 비밀키로 해쉬한 값 === (3) 이고, (2)의 유효기간이 안넘었다면 해당 사용자는 인가받음!
즉!! 서버는 사용자의 상태를 따로 저장할 필요 없이 비밀키만 가지고 있다면, 토큰을 스캔해서 사용자들을 걸러낼 수 있다.
이렇게 JWT 방식처럼 시간에따라 바뀌는 상태값을 가지지 않는것을 Stateless
라고 한다.
( 이것의 반대인 세션은 Stateful
!!)
위의 단점을 완벽히 해결하는것은 아니지만, 어느정도 보완할 수 있는 방법이 있다.
즉, 인가받기 위해서는 유효한 Access Token이 있어야하고, 이 Access Token를 재발급 받기 위해선 Refresh Token이 필요한 것이다.
해당 방법을 통해서...
짧더라도 Access Token 이 살아있는 동안 발생하는 문제는 어쩔 수 없는것이 현재의 한계점이다.
즉 우리 서비스에서 JWT 방식이 문제가 없는지 고민해보고 사용해봐야 할 것이다.
참고문서
https://velopert.com/2389
https://jwt.io/introduction
https://dreamaz.tistory.com/22
유튜브
다음 이야기에서 www.v2와 nx의 인증/인가 방식이 다르다고 하여 이를 정리해보았습니다.