(완료)1. node 강의 듣기 (쿠키, 세션)
(진행중)2. node 3주차 과제 만들어보기
(->)3. 스터디 그룹 운영
서버 죽다 살아났을때 똑같이 동작함
ex) JWT 서버에 별도의 상태 정보를 저장하지 않음. stateless하게 관리.
서버 죽다 살아났을때 조금이라도 다른 동작함.
ex) 쿠키와 세션. 사용자의 로그인 정보, 세션 데이터를 서버에 저장 상태 유지. stateful하게 관리.

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

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, '포트로 서버가 열렸어요!'); });
//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') 클라이언트에게 전달받은 모든 쿠키 정보들이 반환
//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 등장!
쿠키/세션은 데이터를 교환하고 관리하는 방식이고, JWT는 쿠키에 있는 데이터를 JWT형식으로 변경하므로 신뢰성을 올리는 방식.
JWT가 인증서버에서 발급되었는지 위변조 여부 확인가능
누구든지 JWT 내부에 들어있는 정보 확인가능(복호화)
암호화 알고리즘 사용(신뢰성 UP)
Header.paryload.verify signature 으로 구성
참고 사이트: https://jwt.io/
비밀키를 모르더라도 복호화 가능(암호를 풀어서 어떤 내용이 담긴지 확인 가능하다는 말)
JWT 가진 누구나 해당 토큰에 어떤 데이터가 담겼는지 확인 가능
변조만 불가능하고 Payload를 누구나 복호화하여 보는게 가능
단순한 데이터형식
JWT로 만든 데이터는 변조가 어렵고, 서버에 별도의 상태 정보를 저장하지 않기 때문에, 서버를 Stateless(무상태)로 관리가능
쿠키와 세션은 사용자의 로그인 정보나 세션 데이터를 서버에 저장하므로 상태를 유지. 때문에, Stateful(상태 보존)하게 데이터가 관리됨.
Stateless(무상태)와 Stateful(상태 보존)의 차이를 간단히 설명하자면,
Node.js 서버가 언제든 죽었다 살아나도 똑같은 동작을 하면 Stateless하다고 볼 수 있고, 반대로 서버가 죽었다 살아났을때 조금이라도 동작이 다른 경우 Stateful하다고 볼 수 있음.
서버가 스스로 어떤 기억을 갖고 다른 결정을 하냐 마냐의 차이.
로그인 정보를 서버에 저장하게 되면 무조건 Stateful(상태 보존)
import jwt from "jsonwebtoken";
//sign 암호화 const token = jwt.sign({ myPayloadData: 1234 }, "mysecretkey"); console.log(token);
암호화한 jwt형식으로 결과가 반환된다.
const decodedToken = jwt.decode(token); console.log(decodedToken);
const decodedTokenByVerify = jwt.verify(token, "mysecretkey"); console.log(decodedTokenByVerify);
변조되지 않았다면 복호화한 결과를 반환한다.
//verify 변조여부 확인 const decodedTokenByVerify1 = jwt.verify(token, "hey!"); console.log(decodedTokenByVerify1);
JsonWebTokenError 뜸!
import express from "express"; import jwt from "jsonwebtoken"; const app = express(); app.listen(5002, () => { console.log(5002, "번호로 서버가 켜졌어요."); });
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
새로운 프로젝트를 열어서 노드몬 깔고 실행하려고하는데 발생한 에러.

모듈을 잘못찾아서 발생했다는데 내가 한거라곤 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 를 다시 입력해보고 영문을 모르고 있던 중 갑자기 노드몬이 실행되었다.
대체 뭘 수정한거였을까..난...얼렁뚱땅 일단 실행이 되었다.