일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | 4 | 5 | ||
6 | 7 | 8 | 9 | 10 | 11 | 12 |
13 | 14 | 15 | 16 | 17 | 18 | 19 |
20 | 21 | 22 | 23 | 24 | 25 | 26 |
27 | 28 | 29 | 30 |
- 백준
- aws
- QuerySet
- CI
- Continuous Delivery
- Transaction
- Coroutine
- DjangoRestFramework
- DjangoCache
- F객체
- dry-yasg
- Python
- Continuous Deployment
- to_attr
- 도커
- aggregate
- annotate
- testcase
- CD
- 코루틴
- DRF
- apitestcase
- django
- database
- nestedfunction
- racecondition
- Prefetch_related
- docker
- Git
- EC2
- Today
- Total
BackEnd King KY
TIL10 - 서버기반인증과 토큰기반인증 본문
✔️ Intro
인증이라는 단어는 일상에서 많이 들어보셨을겁니다.
하지만 단어에 대해 알고 있어도 그 내부절차나 시스템에 대해 깊게 공부해본 적이 없어서 이번 포스팅을 쓰게 되었습니다.
인증의 경우, 서버 기반으로 인증하는 방법과 토큰 기반으로 인증하는 방법이 있습니다.
기존에는 서버 기반 인증이 많이 사용되었으나, 이제는 토큰 기반 인증을 더 많이 사용하고 있습니다.
서버 기반 인증에 대해 설명한 뒤, 토큰 기반 인증에 대해 작성하겠습니다.
벨로퍼트를 참고하여 작성했습니다.
✔️ 서버 기반 인증
서버 기반 인증은 서버에서 유저 정보를 기억하고 있다가 인증해주는 시스템입니다.
기본적으로 서버에서 유저 정보를 저장하고 있어야 하기 때문에 많이 들어보셨을 쿠키, 세션을 사용하게 되는 것입니다.
쿠키와 세션의 가장 큰 차이는 기록을 웹 브라우저에 저장한다면 쿠키, 서버에 저장한다면 세션입니다.
각설하고, 서버 기반 인증을 많이 사용하던 와중에 몇 가지 문제를 보이기 시작했습니다.
첫 번째는 세션입니다.
쿠키와 세션의 차이를 설명하면서, 세션은 기록을 저장한다고 했는데 저장할 내용이 점점 증가한다면 어떻게 될까요? 서버엔 엄청난 과부하가 오게 될 것입니다.
두 번째로는 확장성입니다.
세션에 저장을 계속 하면 결국 서버 확장에 어려움을 겪게 됩니다. 로드밸런싱에 대해 공부할 때 무조건 나오는 scale-up과 scale-out에 대한 개념이기도 한데, 서버의 개수를 늘리거나 성능을 업그레이드를 한다고 해도 계속 세션에 저장하여 메모리를 잡아먹으면 이 굴레가 무한반복이 됩니다. 그래서 확장성에 대한 문제가 생기게 되는 것입니다.
세 번째로 CORS입니다.
나중에 포스팅 할 내용이기도 하며 Cross-Origin-Resource-Sharing의 약자입니다. 웹 어플리케이션에서 세션을 관리할 때 자주 사용되는 쿠키는 단일 도메인 및 서브 도메인에서만 작동하도록 설계되어 있습니다. 따라서 쿠키를 여러 도메인에서 관리하는 것은 번거롭습니다.
그래서 서버 기반 인증시스템을 그림으로 나타내면 아래와 같게 됩니다.
그리고 이러한 문제들 때문에 토큰 기반 인증시스템을 사용하게 되었습니다.
✔️ 토큰 기반 인증
토큰 기반 인증은 사용자별로 고유하게 부여된 토큰이라는 걸 이용하여 인증하는 방법입니다.
토큰 기반 인증 시스템이 사용된 이유에는 4가지가 있습니다.
첫 번째로 stateless 서버입니다. 저는 http를 배울 때 가장 큰 와닿았던(?) 배웠던 것이 stateless 입니다.
http 요청과 응답은 서로 독립적이어서 영향을 주지 않는 다는 것입니다. 서버 기반 인증의 경우 서버를 계속 켜놓고 세션을 유지해야 하는데, 토큰 기반은 유저마다 정해진 값이 있고, 이 값을 세션이 아닌 로컬 스토리지에 저장하기 때문에 굳이 서버를 계속 켜놓을 필요가 없고 각 요청마다 연결이 안된 독립적인 상태여도 된다는 뜻이 됩니다.
두 번째로 모바일 어플리케이션에 적합하다는 것입니다.
서버에 데이터를 저장하는 건, 서버에 문제가 생기거나 공격이 들어왔을 때 가장 유출되기 쉽다는 특징도 가지고 있습니다. 안전한 API를 만들기 위해선 간단한 토큰 기반 인증이 더 적합합니다.
세 번째로 인증정보를 다른 어플리케이션으로 전달합니다.
예를 들어 카카오 로그인 구현했을 때 순서는 이렇게 됐습니다.
1. 프론트엔드에서 토큰을 보내줌
2. 토큰의 유저정보를 카카오에 요청
3. 카카오에서 토큰을 통해 식별된 유저가 있다면 로그인, 없다면 회원가입
4. 로그인/회원가입 후 우리 웹사이트 이용
이렇게 소셜계정들을 이용하여 다른 웹 서비스로 로그인 할 수 있게 됩니다.
토큰 기반 인증시스템을 그림으로 나타내면 아래와 같이 됩니다.
✔️ 토큰의 장점
결국 위에서 나온 것들이 다 토큰의 장점이 되는 것입니다.
1. stateless라서 별도의 저장할 필요가 없어서
2. 서버 확장에 용이하고
3. 보안성이 뛰어나며
4. 여러 플랫폼에서 사용할 수 있다.
✔️ JWT
그러면 토큰 중 가장 흔하게 사용되는 JWT(JSON Web Token)에 대해 알아보겠습니다.
JWT란 Json 포맷을 이용하여 사용자에 대한 속성을 저장하는 Claim 기반의 웹 토큰입니다.
토큰 자체를 정보로 사용하는 self-contained 방식으로 정보를 안전하게 전달하며, 인증이나 정보전달에 가장 많이 사용됩니다.
로컬 스토리지에 저장되며, 로그인 프로세스를 예시로 들어보겠습니다.
로그인 시, 로컬 스토리지에 값의 존재여부를 체크하며, 있다면 그 값을 이용하여 로그인을 합니다.
없다면 서버에서 헤더의 Authorization에 토큰을 담아서 보내게 됩니다.
✔️ JWT 구조
JWT는 Header, Payload, Signature로 이루어져 있습니다. 그리고 각각의 부분을 구분하기 위해 .을 이용합니다.
첫 번째로 Header입니다.
토큰의 헤더는 타입과 알고리즘 두 가지를 담습니다.
{
"alg" : "HS256",
"typ" : JWT
}
이렇게 쓴다면, 토큰의 알고리즘은 HS256이고 타입은 JWT이 되는 것입니다.
다만 여기서 알고리즘은 헤더를 암호화 하는 게 아닌 Signature를 해싱하기 위한 알고리즘을 지정하는 것입니다.
두 번째로 Payload입니다.
토큰의 페이로드는 토큰에서 사용할 정보의 조각들인 클레임이 담겨있습니다.
토큰을 발행할 때 가장 많이 설정하는 만료 시간같은 게 다 여기 들어가게 됩니다.
마지막으로 Signature입니다.
토큰의 서명은 토큰을 인코딩하거나 유효성 검증할 때 사용하는 고유한 암호화 코드입니다. 헤더와 페이로드의 값을 각각 BASE64로 인코딩하고, 인코딩한 값을 Secret Key로 이용해 헤더에서 정의한 알고리즘으로 해싱하고, 다시 BASE64로 인코딩하여 생성합니다.
✔️ 마치며..
이전 포스팅에서 Django의 패스워드 암호화에 대해 알아봤는데, 바로 이어서 JWT에 대해 알아봤습니다.
회원가입-로그인-토큰발급 이 3가지 프로세스는 뗄레야 뗼 수 없는, 그리고 웹 개발자로서 가장 기초가 되고 알아야 할 근본(?)입니다.
현업에서 열심히 뛰고 계신 모든 개발자분들 화이팅!
'Server' 카테고리의 다른 글
TIL39 - flower (0) | 2022.12.11 |
---|---|
TIL38 - redis (0) | 2022.12.11 |
TIL20 - WSGI & ASGI (0) | 2022.03.15 |