토큰.. 뭔가 동전 이먼저 떠오른다.
동전.. 코인.. 음 -> 입장권 ?
자 내가 만든 토큰이 있다.
나만 이 토큰의 진면목을 알수있다.
그 토큰을 내친구한테 주고
우리집에 올때 그 토큰을 보여주면 들여보내 줄께.
그러면 앞으로 우리집에 올때는 그 토큰이 입장권 이된다.
사설이였고,
클라이언트가 로그인을 시도한다.
-> 서버에서 DB와 데이터 조회를 해서 로그인이 승인될예정이라면
-> jwt(토큰이라고하자)를 만들어준다.
-> set-cookie라는 명령을담은 헤더에담아서.
-> 클라이언트에게 response해준다.
-> 클라이언트는 set-cookie를 읽자마자. 바로 쿠키를 셋팅한다. 즉 전달받은 토큰을 쿠키에 저장한다.(이 의미는 앞으로의 http/https 통신에서 항상 그토큰을 들고서 요청하겠다는 의미이다)
-> 앞으로의 통신에서 토큰을 전달받아서 요청을 처리를하고, 그 토큰이 정상적인지 서버에서 확인만 해주면 이전 게시글에 있던것처럼 세션이 살아있는지 확인하는 것처럼 가는것이다.
토큰의 장점은 서버의 리소스를 좀더 확보할수있고(세션보다 효율적), 수평적 확장에 유리하다. (즉 같은 기능을 하는 서버를 더 늘려도 문제가 없다)
위에서 살짝 설명했지만, 살짝 점진적으로 발전해온 인증의 절차인데.
쿠키만으로 인증 - 세션기반 인증 - 토큰기반 인증
쿠키만으로 인증을하게되면 보안상문제가 취약해진다.
더군다가 클라이언트가 로그아웃했는지 상태를 알기가 어렵다.
세션기반인증은 서버에서 쿠키를관리하는것(세션)으로 사용자의 상태를 서버가 알고있고, 민감한 데이터들을 좀더 숨길수있다. (쉽게 털리기 어렵다)
토큰기반인증은 세션기반보다는.. 사실 조금더 오픈적이긴하다. (즉 보안적으로는 세션이더 강한것이 사실이고) 다만 세션은 서버에 부하를 좀 준다. 그리고 수평적 확장이 불편하다. 쉽게생각하면 3000명의 사용자서비스를 하나의 서버로 세션관리하다가, 두개의 서버로 관리하면 , 하나의 서버에 세션이 살아있어도 다른서버에서는 그 세션을모르기 때문에
또 세션 스토어라는 개념을 도입해서생각해야한다.
주로 redis를 많이쓰는다. 가벼운데이터를 보안상강하게 빠른속도로 읽고써주는 데이터베이스라고 생각하면 좋다.
세션스토어로써 많이 쓰인다고 한다.
JWT는 토큰의 대표적인 이름이라고 봐도 무방하지만.
쉽게생각하면 사용자가 직접 토큰을 만들기 쉽지않기 때문이다.
해시로직을 이용해서 암호화를 하고, 푸는데에는 특정 키가 없을경우 천문학적인 시간을 필요로하게된다.
해시로직에도 여러가지가 있는데 SHA256이 지금으로써는 대중적이고 많이쓰인다고한다. 앞으로도 더 암호화를 깊게 할것으로 보인다.
여기 salt 개념이 살짝 들어가는데.
조미료, 소금 의 의미인다.
특성 해시 로직으로 어떤 정보를 암호화할때
조미료를 좀 쳐서 암호화하면
그 조미료를 모른다면 암호화의 로직을 알더라도 풀기가 무지무지무지무지무지 어려워진다. 말했다 싶이 SHA256이 요즘 대세인 암호화 라고하더라도.
그 salt라는것 을 모르면 못푼다고 생각하면된다.
그래서 그 salt는 -> jwt의 signature 부분이다.
jwt는 기본적으로
머리,가슴,배
3가지로 나눠지는데
header
헤더에는 보통 어떤 알고리즘으로 sign(암호화)할지 적혀있다. 형태는 JSON Web Token에 맞게 JSON형태이다.
payload
정보가 기본적으로 담긴다.
물론 암호화가 될 정보지만, 민감한 정보는 되도록 담지 않는것이 좋다. 더 깊게 들어가면 대부분 이곳에는 권한에 대한 정보가 들어간다.
signature
마지막 블럭으로 비밀키(암호화에 추가할 salt)를 사용하여 암호화한다.
추가적으로 얘기하자면
둘다 사용하는게 요즘 추세? 음.. 가장 베스트프렉티스 ?
라고생각한다.
즉 하나의 인증 처리방식만으로는
단점이 생기므로
둘다사용해서 사용자에게 최고에 경험을 제공하는게
저두가지를 혼용하는것이다. 적절한 상황에 둘다 사용할수있다면
그렇게 구현하는것도 고려해보도록 하자.
사실 나는 여기서 OAuth는 개별적인 얘기 아닌가 ?
라고생각했다.
쿠키,세션,토큰을 배우지않더라도
OAuth는 알수있고, 할수있는거 아닌가? 햇던 과거가 있는데.
땡땡 ,
토큰개념이 나오는것이 있다보니 일단 토큰까지는 알아야하고,
둘째로 일단 지금까지 설명하던것과 조금 달라지는게
바로 third-party이기때문에
사용자(유저&브라우저) -클라이언트단 - 서버단 - 그리고 제3자의 서버
조금 나눠서생각할것이 많아서.
그동안 클라이언트라고하면 사용자 자체를 생각했던 사람들이라면
여기서 약간 뇌정지가 온다.
나도그랬고,
즉
여기서부터는 분리를해서 생각해야한다.
그림이나 레퍼런스자료들을 찾아봐도 쉽게보이는 그런 도식화된 자료를 봐도
사실 한눈에 읽기가 어렵다.
클라이언트단 , 서버단을 잘 숙지 해보자.
사실 크게 2가지 방법으로 나눌수있는데 Oauth라면
대중적인 방법은 리다이렉트 이다.
언어로 설명하면 좀 어려운데.
쉽게생각하면 상대측(소셜미디어? 유명한회사? 서드파티?)과 약속을 어떻게하느냐, 인데
상대측이 여러 서비스들에게 제공하기에 편한것이 사실 리다이렉트일 뿐이라고 나는 생각한다.
순차적으로 가보자.
여기까지는 아직 Authrization코드만 받은 상태 클라이언트가 가지고 있음.
이제 클라이언트는 그 Authrization코드를 내 서비스의 서버로 보낸다. 그러면 내서버는 그것을 받아서. 다시 깃허브의 accessToken을 만들어주는 url로 요청을 보낸다.
3-1. 그 결과 (AuthrizationCode는 깃헙이 내려줬고, 그 코드를 다시 액세스토큰 달라고 서버에서 다시 문두드리면)
액세스토큰을 내려준다.
3-2. 이때 액세스토큰을 서버가 가지고있게되면
3-3. 마찬가지로 set-cookie헤더를 이용해서 클라이언트에 내려주면
클라이언트는 토큰을받고 로그인완료페이지로 이동시켜서 사용자가 로그인된것으로 보여지게 한다(마이페이지등)
이때 마이페이지 즉 어떤 정보를 요구할때-> 토큰이 있으므로 github에서 제공하는 api를 쓸수있다. 유저정보를 어느정도 끌어쓸수있다. 그것은 깃헙 api? oauth페이지를 찾아보면 나온다.
여기까지가 기본적인 flow인데
도식화된 그림으로 살펴보면
위두개의 그림을 어느정도 이해했다면,
실전이 좀더 이해하기 쉬울것이다.