본문 바로가기

개발/프로그래머스 데브코스

프로그래머스 데브코스 27일차 with. TS 웹 풀스택

📚요약

지난 시간에 함수를 모듈화 하다가 문제가 발생했었습니다. 이번 시간에 해결하고 세션, 쿠키를 공부해 보고 JWT 실습을 해보겠습니다.

 

📖미니 프로젝트

📄함수 모듈화 이어하기

지난 시간 발생한 에러 화면

next 인자를 사용하면 단어 그대로 다음 작업을 이어서 진행할 수 있습니다.

const validate = (req, res, next) => {
  const err = validationResult(req);

  if (err.isEmpty()) {
    return next(); // 다음 작업 이어하기
  }

  return res.status(400).json(err.array());
};

 

📖인증과 인가

인증(Authentication)은 참이라는 근거가 있는 무언가를 확인하거나 확증하는 행위로 로그인을 예로 들 수 있다.

인증-위키백과

인가(Authorization)는 리소스에 대한 접근 권한 및 정책을 지정하는 기능이다. 예를 들어 관리자로 로그인할 때와 일반 사용자로 로그인할 때 사용할 수 있는 기능의 차이를 예를 볼 수 있다.

허가-위키백과

 

📖쿠키 vs 세션 vs JWT

📄쿠키(Cookie)

쿠키는 HTTP의 일종으로서 인터넷 사용자가 어떤 웹사이트를 방문할 경우 사용자의 웹 브라우저를 통해 인터넷 사용자의 컴퓨터나 다른 기기에 설치되는 작은 기록 정보 파일

HTTP 쿠키-위키백과

장점

  • 서버가 저장하지 않아서 서버의 저장 공간을 사용하지 않는다
  • Stateless 해서 RESTful 하다

단점

  • 브라우저가 가지고 있기 때문에 임의의 수정과 삭제가 쉽다
  • 가로채기 쉽기 때문에 보안에 취약하다

 

📄세션(Session)

세션은 반영구적이고 상호작용적인 정보 교환을 전제하는 둘 이상의 통신 장치나 컴퓨터와 사용자 간의 대화나 송수신 연결상태를 의미하는 보안적인 다이얼로그 및 시간대를 가리킴

세션-위키백과

장점

  • 브라우저가 아닌 서버가 관리하기 때문에 보안이 비교적 좋다

단점

  • 서버가 저장하기 때문에 서버 자원을 사용한다
  • Stateless 하지 못하다

 

📄JWT(Json Web Token)

쿠키와 세션의 단점을 어느 정도 보완한 것입니다. 완벽하게 보완이 된 것은 아닙니다.

JWT는 당사자 간에 정보를 JSON 객체로 안전하게 전송하기 위한 간결하고 독립적인 방법을 정의하는 개방형 표준

 

장점

  • 암호화되어 있기 때문에 보안에 강하다
  • Stateless 하다
  • 서버에 저장하지 않기 때문에 서버에 부담이 적다
  • 추가적으로 토큰을 발행하는 서버를 따로 만들 수 있다

구조

  • HEADER : 암호화 시 사용한 알고리즘(alg)과 토큰의 형태(typ)를 저장
  • PAYLOAD : 보내고자 하는 데이터
  • VERIFY SIGNATURE : 데이터를 보내는 사람을 증명하는 것 즉 서명이다. 만약 payload 값이 바뀌면 서명값이 통째로 바뀌기 때문에 믿고 사용할 수 있다

자세한 내용은 공식 홈페이지를 참고해 보시면 좋을 것 같습니다.

 

JWT.IO

JSON Web Tokens are an open, industry standard RFC 7519 method for representing claims securely between two parties.

jwt.io

 

📖JWT

📄인증, 인가 절차(로그인)

클라이언트 요청/응답 서버
1. 로그인 요청(POST) Body - id, pw 2. 내부 로직 확인
4. 로그인 유지 3. JWT 발행(서명) 및 응답
5. 다른 요청(주문, 장바구니 등) Header - JWT  6. JWT 서명 확인
8. 로그인 유지 및 작업 진행 7. 서명이 맞으면 응답

 

📄구현(JWT 발행)

이번에는 jsonwebtoken 패키지를 사용해서 JWT를 발행시켜 보겠습니다.

const jwt = require("jsonwebtoken");
const token = jwt.sign({ foo: "bar" }, "shhhh");
console.log(token);

// eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.
// eyJmb28iOiJiYXIiLCJpYXQiOjE3MTU2NzkxNDZ9.
// LOg6MYYtuxN-TIUNYrLrIF-kNPCXX1JMlte8IVTdYlk

 

발행된 토큰을 가지고 공시 홈페이지에서 테스트해 볼 수 있습니다.

발행된 토큰을 Encoded에 넣었을 때 결과

그런데 왜 Invalid Signature라고 뜨는가? 바로 VERIFY SIGNATURE 칸에 저희의 서명인 'shhh'를 넣어주지 않았기 때문입니다.

서명까지 완료한 결과

서명까지 완료하니 성공한 것을 볼 수 있습니다. 그렇다면 payload 값을 코드에서도 꺼내보겠습니다.

const jwt = require("jsonwebtoken");
const token = jwt.sign({ foo: "bar" }, "shhhh");
const decoded = jwt.verify(token, "shhhh");
console.log(decoded);

// { foo: 'bar', iat: 1715679416 }
🍯tip! iat는 무엇인가? issued at으로 토큰이 발행된 시간입니다. 해당 값 때문에 토큰을 발행할 때마다 다른 결과 값이 나타나는 것을 확인할 수 있습니다.
🍯tip! .env 파일을 사용해 기본 설정 값을 외부에 공개하지 않고 환경 변수들을 따로 관리할 수 있다. npm에 dotenv라는 패키지를 이용해 쉽게 사용할 수 있다.

📖미니 프로젝트(Library)

📄JWT 적용

위 코드를 활용해 로그인하면 토큰을 보내주도록 만들어 보겠습니다.

login 시 JWT 토큰을 생성해 보내주는 결과

자세한 코드는 Github에 올라가 있습니다.

 

ProgrammersSchool/NORMAL-LIBRARY at main · nulzi/ProgrammersSchool

프로그래머스 데브코스에서 학습하는 것들을 모아두는 레포. Contribute to nulzi/ProgrammersSchool development by creating an account on GitHub.

github.com

 

다음 시간에 계속...

 

출처 & 참고

김송아 강사님의 강의

web.cookie and session, nulzi, 2024.05.14