2023. 1. 20. 04:02ㆍNodeJs
| 목차 |
| 1. 쿠키(Cookie)와 세션(Session) |
| 2. 암호화 |
| 3. JWT(JSON Web Token) |
HTTP 프로토콜은 기본 스펙은 비연결성이다.
3 way hand shake 연결 후에 한 번의 요청과 응답 메시지를 주고받은 후에 4 way hand shake로 연결을 끊는다.



즉, 메시지를 주고 받은 후 바로 연결을 끊기 때문에 비연결성이라고 하는 것이다.
이 떄, 로그인시 내가 누군지 증명을 해야하는데 비연결성으로 인해서 내가 누구인지 증명하기가 어려웠다.
그것을 증명하기 위한 방법으로 쿠키, 세션이라는 개념이 등장했다.
1. 쿠키(Cookie)와 세션(Session)
쿠키의 사용으로 비연결성이라는 문제를 해결할 수 있다.
브라우저(클라이언트)에는 데이터를 저장할 수 있는 저장소가 있다.
- 로컬스토리지
- 세션스토리지
- 쿠키
이 중 쿠키를 이용한 로그인 방식을 알아보자.
쿠키를 이용한 회원가입 및 로그인
- 서버는 클라이언트에게 받은 데이터를 쿠키에 저장하라고 응답메시지에 담아 보낸다.
- 응답메시지(쿠키)를 받은 브라우저는 쿠키의 옵션에 맞게 요청메시지에 항상 넣어 보낸다.
- 서버는 요청 메시지를 받아 해당 브라우저가 이전의 브라우저임을 확인할 수 있다.


쿠키의 단점
쿠키를 통해 비연결성의 문제점은 해결되지만, 쿠키에는 몇 가지 단점이 존재한다.
보안성의 취약
쿠키에 담긴 중요한 데이터를 쉽게 볼 수 있다.
- 요청 메시지를 중간에 가로챈다면, 그 안에 담긴 중요한 데이터가 유출될 수 있다.
저장 용량이 작다
쿠키의 저장 용량은 최대 4KB로 매우 작은 양을 저장할 수 있다.
- 쿠키에 많은 데이터를 담고 싶어도 담을 수가 없다.
요청 데이터의 증가
사용하지 않는 데이터도 매번 요청메시지 헤더에 넣어 보내기 때문에 필요이상으로 요청 데이터가 증가한다.
세션(Session)
쿠키의 단점을 보완하기 위해서 세션을 사용하기도 한다.
세션이란, 쿠키를 이용해서 데이터를 백엔드서버에 맡기는 것이다.
데이터의 중요 내용을 서버에 맡겨 보안성 문제를 해결하고자 했다.
식별은 쿠키방식과 마찬가지로 쿠키를 이용하고, 보여져서 안되는 중요한 데이터는 데이터베이스에 담아두는 방식이다.


세션의 단점
보안성 문제를 해결한 세션방식에도 단점은 존재했다.
만약, 사용자가 많아 데이터의 양이 늘어난다면 어떻게 될까?
서버에 부하가 늘어나게 된다. 이를 해결하기 위해 서버 컴퓨터를 늘리거나, 업그레이드를 하여 해결해왔다.
쿠키와 세션의 차이점
둘다 쿠키를 이용하는 것은 같지만 데이터의 저장 방법이 달랐다.
둘 중 무엇이 더 뛰어나다고 할 수 없고, 현재에도 두 방식 모두 이용하고 있는 서버가 많다.
오늘 알아볼 JWT는 쿠키의 방식을 보안하여 탄생하게 되었다.
2. 암호화
JWT를 알아보기에 앞서 간단히 알아둬야할 내용이 있다.
바로 암호화다.
암호화란 원치않는 누군가가 볼 수 없도록 당사자들만 알 수 있도록 하는 것이다.
사람이 읽을 수 있는 것을 평문이라하고, 평문은 읽을 수 없도록 바꾸는 것이 암호화이다.
반대로 암호화된 것을 평문으로 바꾸는 것을 복호화라고 한다.

암호화는 크게 두 가지로 나뉜다.
복호화로 되냐 안되냐로 구분할 수 있다.
단방향
단방향 암호화에는 Hash라는 대표적인 것이 있고, 블록체인에도 쓰인다.
양방향
양방향 암호화에는 대칭키와 비대칭키가 있는데,
둘의 차이는 암호화를 진행한 쪽과 복호화를 진행하는 쪽의 데이터의 모양이 같냐 다르냐로 구분된다.
3. JWT(JSON Web Token)
JWT는 기존 로그인 방식의 단점을 보완해주었다.
쿠키를 이용하는 것은 같지만, 쿠키의 모양을 암호화하되 규격화한다는 개념으로부터 출발한다.
JWT를 이용하면 간편로그인과 같은 로그인 방식이 가능해진다.(쿠키의 모양이 일치함을 이용)
특징
JWT는 다음과 같은 특징을 갖는다.
- Cookie를 이용한다.
- 규격화되었다.(일종의 프로토콜)
JWT의 구조
JWT의 생김새를 한번 살펴보자.

JWT의 J는 JSON을 의미하며, 헤더와 페이로드 부분역시 JSON임을 알 수 있다.
- Header 부분은 서명시에 사용하는 알고리즘과 토큰의 타입이 들어간다.
- HS256: 대칭 암호화의 한 유형으로 토큰 서명 및 확인을 하는데 개인키를 사용한다.
- RS256: 비대칭 암호화의 한 유형으로 토큰 서명 및 확인을 위해 개인키와 공개키가 필요하다.
- Payload 부분은 JWT의 데이터를 넣어준다.
- 페이로드에 있는 속성을 클레임셋이라고 부른다.
- 클레임 셋은 토큰의 정보, 생성일시나, 만료기간, 클라이언트-서버간 데이터들로 구성된다.
- Signature 부분은 헤더와 페이로드 부분을 합쳐 암호화를 진행하여 만들어진다.
- header + "." + payload, 비밀키
- 보안 서명을 통해 메세지가 전송 과전에서 바뀌지 않았음을 확인한다.
- 어떤 형태로 암호화 했는지 알려서는 안된다.(비밀키)
JWT의 구현
코드를 통해서 JWT는 어떻게 구현되는지 알아보자.
// 내장 모듈을 불러온다.
const crypto = require('crypto')
// header에 알고리즘과 토큰의 타입을 넣어준다.
const header = {
alg:"HS256",
typ: "JWT",
}
// payload에 데이터들을 입력한다.
const payload = {
sub: "1234567890",
userid: "admin",
username:"admin",
age: 32,
iat: 1516239022,
}
// header와 payload를 인코딩해주는 함수선언
function encode(obj){
return Buffer.from(JSON.stringify(obj)).toString("base64url")
}
const header64 = encode(header)
const payload64 = encode(payload)
const context = header64 + "." + payload64
// 암호화를 통한 signature 생성
const signature = crypto.createHmac('sha256', 'web7722').update(context).digest('base64url')
console.log(header64)
// eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9
console.log(payload64)
// eyJzdWIiOiIxMjM0NTY3ODkwIiwidXNlcmlkIjoiYWRtaW4iLCJ1c2VybmFtZSI6ImFkbWluIiwiYWdlIjozMiwiaWF0IjoxNTE2MjM5MDIyfQ
console.log(signature)
// -GjlkauvQLPeOPimlF9w-2dI7NiYY7VcDh-9kAWijEo
콘솔에 찍힌 내용을 가지고 JWT 공식 홈페이지에서 잘 변환 되었는지 확인해 보도록하자.
헤더와 페이로드를 넣고, 비밀키를 넣어주면 시그니처가 자동으로 생성된다.

참고자료
https://jwt.io/
https://baekspace.tistory.com/114
'NodeJs' 카테고리의 다른 글
| NodeJs.multer(npm 패키지, 파일 업로드하기) (0) | 2023.01.25 |
|---|---|
| NodeJs. JWT(JSON Web Token) 만들기 (0) | 2023.01.22 |
| NodeJs.ORM - Sequelize(2) (0) | 2023.01.13 |
| NodeJs.ORM - Sequelize(1) (1) | 2023.01.11 |
| NodeJs.ORM(Object Relational Mapping) (0) | 2023.01.11 |