[23.11.03] TIL

yy·2023년 11월 2일

개발일지

목록 보기
21/122
post-thumbnail

오늘 할 일

(완료)1. node 강의 듣기 (쿠키, 세션)
(진행중)2. node 3주차 과제 만들어보기
(->)3. 스터디 그룹 운영


Stateless

서버 죽다 살아났을때 똑같이 동작함
ex) JWT 서버에 별도의 상태 정보를 저장하지 않음. stateless하게 관리.

Stateful

서버 죽다 살아났을때 조금이라도 다른 동작함.
ex) 쿠키와 세션. 사용자의 로그인 정보, 세션 데이터를 서버에 저장 상태 유지. stateful하게 관리.


🍪 쿠키

  • 사용자가 웹 사이트를 방문할 때마다 이전에 방문했던 정보를 기억하는 데이터 파일.
  • 데이터를 여러 사이트에 공유할 수 있기 때문에 보안에 취약할 수 있음.
  • 만료기간 있음.

  • 클라이언트 -> 서버 요청 보낼 때는 쿠키가 없음.
  • 서버 -> 클라이언트 응답 보낼 때는 쿠키 생성해서 응답 보내줌(Set-Cookie 헤더를 전송.)
  • 클라이언트 -> 서버 요청 보낼 때는 요청 + 쿠키 (Cookie HTTP Header안에 포함되어 전달받음)
  • 서버 -> 클라이언트 응답 보낼 때도 응답 + 쿠키

📬세션

  • 쿠키를 기반으로 구성된 기술. 단, 클라이언트가 마음대로 데이터를 확인 할 수 있던 쿠키와는 다르게 세션은 데이터를 서버에만 저장.
  • 일반적으로 세션 Id를 쿠키를 이용해 클라이언트에게 전달하여, 서버는 이 세션 Id를 사용해 저장된 세션 데이터를 조회.
  • 세션을 통해 사용자의 상태 정보를 서버에 저장하면, 서버는 사용자의 상태를 추적할 수 있음.
  • 만료기간 있음.

쿠키타고 세션 ID가 서버와 브라우저를 왔다갔다하므로 서버로 요청을 보낼 때마다 내가 누군지 증명 안해도됨.
세션 DB와 비교하고 세션ID가 있는 DB는 얘가 누군지 기억하게 됨

    1. 클라이언트 -> 서버 요청 보낼 때 ID, PW 알려줌
    1. 서버는 요청을 받아 session DB에 저장하여 세션 ID를 생성 후
    1. 서버 -> 클라이언트 : 세션 ID를 클라이언트한테 쿠키랑 같이 보냄
    1. 클라이언트는 쿠키+세션ID를 받아서 브라우저에 저장
    1. 클라이언트 -> 서버 다시 요청 보낼 때 쿠키에 묻어있던 세션 ID와 세션DB를 비교하여 클라이언트가 누구인지 기억하게 됨.

1. yarn init -y

  • express
  • cookie-parser : 쿠키를 req.cookies 객체로 만들어주는 미들웨어(원래 쿠키쓰려면 req.headers.cookie로 써야했음)
import express from 'express';
import cookieParser from 'cookie-parser';

const app = express();
const PORT = 5001;

app.use(express.json());
app.use(cookieParser());

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

4-1. 쿠키 만들고 접근하기

//app.js
import express from 'express';
import cookieParser from 'cookie-parser';

const app = express();
const PORT = 5001;

app.use(express.json());
app.use(cookieParser());

// 쿠키 이용
app.get('/set', (req, res) => {
  res.cookie('name', 'nodejs');
  //res.cookie를 통해 클라이언트한테 쿠키를 전달할 수 있음
  return res.status(200).end();
});

app.get('/get', (req, res) => {
  const cookies = req.cookies;
  console.log(cookies);
  return res.status(200).json({ cookies });
});

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

👆 ('/set') name이라는 이름을 가진 “nodejs” 문자열을 저장한 쿠키를 반환 👆 ('/get') 클라이언트에게 전달받은 모든 쿠키 정보들이 반환


4-2. 세션 만들고 접근해보기

//app.js
import express from 'express';
import cookieParser from 'cookie-parser';

const app = express();
const PORT = 5001;

app.use(express.json());
app.use(cookieParser());

// 세션이용 (uniqueInt에 시간을 넣어서 구분하기)
let session = {};
app.get('/set-session', (req, res) => {
  const name = '윤영';
  const uniqueInt = Date.now();
  session[uniqueInt] = { name };

  console.log(session[uniqueInt]); //{ name: '윤영' }

  res.cookie('sessionKey', uniqueInt);
  // sessionKey를 발급할건데 그 안에 uniqueInt로 sessionKey를 조회할 수 있음.
  return res.status(200).end();
});

app.get('/get-session', (req, res) => {
  const { sessionKey } = req.cookies;
  console.log(req.cookies); //{ sessionKey: '1699348802445' }
  console.log(sessionKey); //1699348721612 -> 할 때마다 변경됨
  console.log(session); //{ '1699348721612': { name: '윤영' } }
  const name = session[sessionKey];
  console.log(name); //{ name: '윤영' }
  return res.status(200).json({ name });
});

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

/set-session을 통해 세션ID발급하고, /get-session으로 확인할 수 있음

만약 /get-session/set-session보다 먼저 실행하면 session에 아무것도 안나옴!




🔐JWT (Json Web Token)

쿠키 단점의 단점으로는 클라이언트가 가져온 쿠키가 내 서버에서 발급한게 맞는지 확인이 안됨. 다른 홈페이지에서 발급한 아이디를 가져와서 로그인되게 해달라는 격.
그래서 이러한 문제를 해결하기 위해 JWT 등장!
쿠키/세션은 데이터를 교환하고 관리하는 방식이고, JWT는 쿠키에 있는 데이터를 JWT형식으로 변경하므로 신뢰성을 올리는 방식.

  • JWT가 인증서버에서 발급되었는지 위변조 여부 확인가능

  • 누구든지 JWT 내부에 들어있는 정보 확인가능(복호화)

  • 암호화 알고리즘 사용(신뢰성 UP)

  • Header.paryload.verify signature 으로 구성
    참고 사이트: https://jwt.io/

  • 비밀키를 모르더라도 복호화 가능(암호를 풀어서 어떤 내용이 담긴지 확인 가능하다는 말)

  • JWT 가진 누구나 해당 토큰에 어떤 데이터가 담겼는지 확인 가능

  • 변조만 불가능하고 Payload를 누구나 복호화하여 보는게 가능

  • 단순한 데이터형식

  • JWT로 만든 데이터변조가 어렵고, 서버에 별도의 상태 정보를 저장하지 않기 때문에, 서버를 Stateless(무상태)로 관리가능

  • 쿠키와 세션은 사용자의 로그인 정보나 세션 데이터를 서버에 저장하므로 상태를 유지. 때문에, Stateful(상태 보존)하게 데이터가 관리됨.

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

  • 서버가 스스로 어떤 기억을 갖고 다른 결정을 하냐 마냐의 차이.

  • 로그인 정보를 서버에 저장하게 되면 무조건 Stateful(상태 보존)


1. yarn init -y

2. yarn add jsonwebtoken express

3. 파일 생성 및 jwt import 하기

import jwt from "jsonwebtoken";

4-1. 암호화 (sign)

//sign 암호화
const token = jwt.sign({ myPayloadData: 1234 }, "mysecretkey");
console.log(token);


암호화한 jwt형식으로 결과가 반환된다.

4-2. 복호화 (decode)

const decodedToken = jwt.decode(token);
console.log(decodedToken);

4-3-1. 변조여부 확인 (verify)

const decodedTokenByVerify = jwt.verify(token, "mysecretkey");
console.log(decodedTokenByVerify);


변조되지 않았다면 복호화한 결과를 반환한다.

4-3-2. signiture를 바꾼다면?!

//verify 변조여부 확인
const decodedTokenByVerify1 = jwt.verify(token, "hey!");
console.log(decodedTokenByVerify1);


JsonWebTokenError 뜸!


jwt를 적용한 로그인 API

1. 기본틀 잡기(라이브러리 import, port)

import express from "express";
import jwt from "jsonwebtoken";

const app = express();

app.listen(5002, () => {
  console.log(5002, "번호로 서버가 켜졌어요.");
});

2.post로 사용자 정보 등록

app.post("/login", (req, res) => {
  //사용자 정보
  const user = {
    userId: 203,
    email: "dbsdud131@gmail.com",
    name: "정윤영",
  };

  //사용자 정보 JWT
  const userJWT = jwt.sign(user, "mysecreteKey", { expiresIn: "1h" });

  //userJWT 변수를 sparta라는 이름을 가진 쿠키에 전달
  res.cookie("sparta", userJWT);
  return res.status(200).end();
});


insomnia에서 post를 보내고 쿠키를 확인해보면 jwt형식으로 잘 들어간걸 확인할 수 있다.

jwt.io 에서 확인했을때도 잘나온다.
payload부분에 ian와 exp가 나오는데 1시간으로 설정해둬서 두 값의 차이가 3600 나는걸 볼 수 있다.



[참고]
https://puleugo.tistory.com/138


👊💥트러블슈팅

Error [ERR_MODULE_NOT_FOUND]

새로운 프로젝트를 열어서 노드몬 깔고 실행하려고하는데 발생한 에러.

모듈을 잘못찾아서 발생했다는데 내가 한거라곤 src 폴더 안으로 옮겼던 것 뿐인데...
package.json 폴더의 scripts의 폴더 위치도 바꿨고, 뭐가 잘못된건지 알수가 없었다.

업로드중..

검색해보니 node_modules와 무슨 충돌이 발생해서 그럴 수 있다고 해서 모듈들을 지웠다가 다시 깔아본 상태였다.
참고: https://selfish-developer.com/entry/error-internalmodulescjsloaderjs883

rm -rf node_modules
rm -f package-lock.json
yarn cache clean
yarn install

그래도 안되길래 nodemond /src/app.js 와 yarn start 를 다시 입력해보고 영문을 모르고 있던 중 갑자기 노드몬이 실행되었다.
대체 뭘 수정한거였을까..난...얼렁뚱땅 일단 실행이 되었다.

업로드중..

profile
시간이 걸릴 뿐 내가 못할 건 없다.

0개의 댓글