스파르타 Node.js 숙련 2 (COOKIE & SESSION & JWT)

병아리의최후·2022년 12월 19일
0

Node.js

목록 보기
7/13

01. 쿠키와 세션

1. 쿠키와 세션이란?

  • 쿠키(Cookie): 브라우저가 서버로부터 응답으로 Set-Cookie 헤더를 받은 경우 해당 데이터를 저장한 뒤 모든 요청에 포함하여 보낸다.
    • 데이터를 여러 사이트에 공유할 수 있기 때문에 보안에 취약.
    • 쿠키는 userId=user-1321;userName=sparta 와 같이 문자열 형식으로 존재하며 쿠키 간에는 세미콜론(;) 으로 구분.
  • 세션(Session): 쿠키를 기반으로 구성된 기술이다. 단, 클라이언트가 마음대로 데이터를 확인 할 수 있던 쿠키와는 다르게 세션은 데이터를 서버에만 저장하기 때문에 보안이 좋으나, 반대로 사용자가 많은 경우 서버에 저장해야 할 데이터가 많아져서 서버 컴퓨터가 감당하지 못하는 문제가 생길 수 있다.

2. 쿠키와 세션 코드로 써보기

02. JWT란 무엇인가?

1. 정리

  • JSON 형태의 데이터를 안전하게 교환하여 사용할 수 있게 해준다.
  • 인터넷 표준으로서 자리잡은 규격.
  • 여러가지 암호화 알고리즘 사용가능.
  • header.payload.signature 의 형식으로 3가지의 데이터를 포함. (개미처럼 머리, 가슴, 배)
    때문에 JWT 형식으로 변환 된 데이터는 항상 2개의 . 이 포함된 데이터여야 한다.

2. 어떻게 생김?

https://jwt.io/ 에서 간단히 확인 가능하다.

  • header(머리)는 signature(배)에서 어떤 암호화를 사용하여 생성된 데이터인지 표현한다.
  • payload(가슴)는 개발자가 원하는 데이터를 저장한다.
  • signature(배)는 이 토큰이 변조되지 않은 정상적인 토큰인지 확인할 수 있게 도와준다.

3. 더 알아야 할게 있음?

  • JWT는 암호 키(Secret Key)를 모르더라도 복호화(Decode)가 가능하다.
    변조만 불가능 할 뿐, 누구나 복호화하여 보는것은 가능하다는 의미
  • 때문에 민감한 정보(개인정보, 비밀번호 등)는 담지 말자.
  • 특정 언어에서만 사용 가능한것은 아니다.
    단지 개념으로서 존재하고, 이 개념을 코드로 구현하여 공개된 코드를 우리가 사용하는게 일반적.

4. 그래서 쿠키,세션과 뭐가 다른건데?

데이터를 교환하고 관리하는 방식인 쿠키/세션과 달리, JWT는 단순히 데이터를 표현하는 형식임

  • JWT로 만든 데이터를 브라우저로 보내도 쿠키처럼 자동으로 저장되지는 않지만, 변조가 거의 불가능하고 서버에 데이터를 저장하지 않기 때문에 서버를 Stateless(무상태)로 관리할 수 있다. 그래서 요즘 많이 쓰인다.

  • Stateless(무상태)Stateful(상태 보존)의 차이를 간단히 설명하자면,
    Node.js 서버가 언제든 죽었다 살아나도 똑같은 동작을 하면 Stateless
    반대로 서버가 죽었다 살아났을때 조금이라도 동작이 다른 경우 Stateful

  • 즉, 서버가 스스로 어떤 기억을 갖고 다른 결정을 하냐 마냐의 차이라고 보면 더 쉽다.

  • 로그인 정보를 서버에 저장하게 되면 무조건 Stateful(상태 보존)이라고 볼 수 있다.

03. JWT는 어떻게 사용하지?

1. 오픈소스 라이브러리 이용

npm init
npm i jsonwebtoken -S

설치해주자.

2. 원하는 JSON 데이터를 암호화

3. 복호화

그리고 검증


검증을 하는 이유는
1. 암호화를 할 때 사용한 비밀키가 일치하는지 확인할려고
2. 해당하는 jwt가 만료되었는지 확인할려고

-- + 만료시간 코드에 추가해주자

4. 암호화된 데이터는 어떻게 사용할까?

놀이공원에 비유해볼까?

  • 회원가입: 회원권 구매
  • 로그인: 회원권으로 놀이공원 입장
  • 로그인 확인: 놀이기구 탑승 전마다 유효한 회원권인지 확인
  • 내 정보 조회: 내 회원권이 목에 잘 걸려 있는지 확인하고, 내 이름과 사진, 바코드 확인

04. Access Token, Refresh Token

1. Access Token?

Access Token은 사용자의 권한이 확인(ex: 로그인) 되었을 경우 해당 사용자를 인증하는 용도로 발급

이전에 발급한 jwt또한 Access Token이라고 부를 수 있다.

사용자가 Access Token을 가지고 인증을 요청할 경우 Token을 생성할 때
사용한 비밀키(Secret Key)를 가지고 인증하기 때문에, 복잡한 설계없이 코드를 구현할 수 있고, 여러 분기를 거치지 않아도 된다는 장점 존재.

Stateless(무상태) 즉, jwt를 이용해 사용자의 인증 여부는 확인할 수 있지만,
처음 발급한 사용자 본인인지 확인할 수는 없다.

Access Token은 그 자체로도 사용자를 인증하는 모든 정보를 가지고 있다.
그렇기 때문에 탈취 당했을 때 피해 막심...

2. Refresh Token?

Refresh Token은 Access Token 처럼 해당하는 사용자의 모든 인증 정보를
관리하는 것이 아닌, 특정한 사용자가 Access Token을 발급받을 수 있게 하기
위한 용도로만 사용

Refesh Token은 사용자의 인증정보를 사용자가 가지고 있는 것이 아닌, 서버에서 해당 사용자의 정보를 저장소 또는 별도의 DB에 저장하여 관리.
그렇기 때문에, 서버에서 특정 Token 만료가 필요할 경우 저장된 Token을 제거하여 사용자의 인증 여부를 언제든지 제어가 가능.

그럼 왜 바로 Access Token을 발급하지 않고, Refresh Token을 거쳐서 Access Token을 발급함?
사용자에게 발급한 Token이 탈취당할 경우 피해를 최소화 하기 위해서 사용

실제 사용하는 OTP와 같이 짧은 시간 내에서만 인증 정보를 사용할 수 있게하고,
주기적으로 재발급하여, 토큰이 유출되더라도 오랜 기간동안 피해를 입는것이 아닌,
짧은 기간동안만 사용가능하도록 하여 피해를 최소화.

3. Refresh Token Project의 템플릿을 만들어 보자!

먼저 셋팅부터

npm init -y
npm install express jsonwebtoken cookie-parser -S

설치해주고

// app.js

const jwt = require("jsonwebtoken");
const cookieParser = require("cookie-parser");
const express = require("express");
const app = express();
const port = 3002;
const SECRET_KEY = `HangHae99`;

app.use(cookieParser());

app.get("/", (req, res) => {
  res.status(200).send("Hello Token!");
})

app.listen(port, () => {
  console.log(port, '포트로 서버가 열렸어요!');
})

연결 잘 됐나 확인해주고 스타트

4. Refresh Token과 Access Token을 발급하는 API

사용자가 GET /set-token/:id API를 호출했을때 Access Token과 Refresh Token을 2개 발급하게 되고, Refresh Token을 Key 값으로 입력된 id를 찾을 수 있게 구현

그리고 accessToken, refreshToken이라는 Key로 Cookie를 2개 발급

5. Refresh Token과 Access Token을 검증하는 API

6. Thuner Client로 API 테스트

  • GET /set-token/:id API 호출

  • GET /get-token API 호출

왜 인증되었다는 메세지가 아닌 새롭게 발급되었다는 메세지가 응답한걸까?

이유는 Access Token을 생성할 때, 10초의 만료기간을 설정하였고(30번째 줄)

토큰을 확인하기까지 10초이상의 시간을 소모했기 때문.

그럼 빠르게 Send를 2번눌러서 정상적으로 메세지가 호출되는걸 확인해볼까?

  • GET /get-token API의 정상적인 Response 확인

GET /set-token/:id API에서 84의 Payload를 가진 Token을 만들었던 정보를 확인

굿..


Access Token과 Refresh Token을 비교했을 때, 프로젝트를 빠르게 구현해야하거나 사용자의 요청에 대한 인증을 최소화 하기 위해서는 Access Token을 사용

보안성을 중요시 여기고, 서버를 좀더 탄탄하게 구성해야 할 경우에는 Refesh Token을 사용

0개의 댓글

관련 채용 정보