[TIL]
[TIL] 2024.01.26 JWT
재호링
2024. 1. 27. 01:28
오늘 한 일
- Cookie Session
- JWT(Json Web Token)
- community-hub
문제점
- 서버에서 어떤 방식으로 쿠키를 사용하나
쿠키는 req.headers.cookie에 들어있다.
req.headers는 Request의 헤더를 의미함.
// 'req.headers.cookie'를 이용하여 클라이언트의 모든 쿠키를 조회하는 API
app.get('/get-cookie', (req, res) => {
const cookie = req.headers.cookie;
console.log(cookie); // name=jaehoring
return res.status(200).json({ cookie });
});
- cookie-parser 미들웨어는 req.headers.cookie와 같이
길게 쓰지 않고 req.cookies로 사용된다. 객체 형태로 저장 가능하기 때문에 편한 것이 장점.
쿠키를 더 쉽게 사용하게 해주는 미들웨어.
yarn add cookie-parser
- 쿠키는 조작되거나 노출되면 안된다. 보안에 문제가 되기 때문.
그래서식별 정보를 확실하게 구분할 수 있는 정보를 내포하고 있다.
민감한 정보는 서버에서 관리하고 식별 정보를 통해 사용자 정보를 반환해주는 것
- Session은 서버에서 사용자 정보를 저장하기 위해 사용함.
set, get session API가 호출되면 변수 정보를 세션에 삽입하고
해당 데이터를 검색하기 위한 시간 정보를 쿠키로 반환하는 것.
import express from 'express';
import cookieParser from 'cookie-parser';
const app = express();
const PORT = 5001;
app.use(express.json());
app.use(cookieParser());
// 'req.cookies'를 이용하여 클라이언트의 모든 쿠키를 조회하는 API
app.get('/get-cookie', (req, res) => {
const cookies = req.cookies;
console.log(cookies);
return res.status(200).json({ cookie: cookies });
});
let session = {};
app.get('/set-session', function (req, res, next) {
// 현재는 sparta라는 이름으로 저장하지만, 나중에는 복잡한 사용자의 정보로 변경될 수 있습니다.
const name = 'sparta';
const uniqueInt = Date.now();
// 세션에 사용자의 시간 정보 저장
session[uniqueInt] = { name };
res.cookie('sessionKey', uniqueInt);
return res.status(200).end();
});
app.get('/get-session', function (req, res, next) {
const { sessionKey } = req.cookies;
// 클라이언트의 쿠키에 저장된 세션키로 서버의 세션 정보를 조회합니다.
const name = session[sessionKey];
return res.status(200).json({ name });
});
app.listen(PORT, () => {
console.log(PORT, '포트로 서버가 열렸어요!');
});
- JWT = json web token
jwt는 비밀키를 모르더라도 복호화가 가능하다.
변조가 불가능하지 복호화하여 보는것은 가능함. - 무상태(stateless)와 상태보존(stateful)의 차이.
서버가 죽었따 살아나도 똑같은 동작을 한다면 상태보존 즉, (statefull) 하다고 볼 수 있음.
반대로 서버가 죽었다 살아낫을때 조금이라도 동작이 다를 경우 무상태 즉, stateless 하다고 볼 수 있음.
JWT 사용 방법
# yarn을 이용해 프로젝트를 초기화합니다.
yarn init -y
# jsonwebtoken, express 라이브러리를 설치합니다.
yarn add jsonwebtoken express
- jwt는 헤더, 패이로드, 서명 으로 구성되어 있음.
- 헤더
{
"alg": "HS256",
"typ": "JWT"
}
- 패이로드 - 실제 전달하려는 데이터. (개발자가 원하는 데이터)
{
"sub": "1234567890",
"name": "John Doe",
"iat": 1516239022
}
- 서명(Signature)
헤더와 패이로드, 비밀키를 이용해 생성.
변조되지 않은 정상적인 토큰인지 확인할 수 있게 도와줌.
HMACSHA256(
base64UrlEncode(header) + "." +
base64UrlEncode(payload),
secret
)
- 데이터 암호확 과정
import jwt from 'jsonwebtoken';
const token = jwt.sign({ myPayloadData: 1234 }, 'mysecretkey');
console.log(token); // eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJteVBheWxvYWREYXRhIjoxMjM0LCJpYXQiOjE2OTA4NzM4ODV9.YUmYY9aef9HOO8f2d6Umh2gtWRXJjDkzjm5FPhsQEA0
- 우리가 담을 데이터는 페이로드에
- sign 메서드는 첫 번째 인자로 페이로드 데이터를, 두 번째 인자로 비밀 키를 받음.
- 페이로드는 문자열 뿐만 아니라, 객체도 할당할 수 있음.
복호화(Decode) 하는 과정도 쉬움
- 복호화를 하려면 변수를 하나 선언하고 jwt.decode(token)을 삽입해주면됨.
import jwt from 'jsonwebtoken';
const token = "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJteVBheWxvYWREYXRhIjoxMjM0LCJpYXQiOjE2OTA4NzM4ODV9.YUmYY9aef9HOO8f2d6Umh2gtWRXJjDkzjm5FPhsQEA0";
const decodedValue = jwt.decode(token);
console.log(decodedValue); // { myPayloadData: 1234, iat: 1690873885 }
변조되지 않은 데이터인지 검증하는 법
- verify 메서드를 활용해 jwt를 검증가능.
verify 메서드는 뒤에 비밀 키 인자 값을 넣어줘 서명되었는지 검증을 함.
import jwt from 'jsonwebtoken';
const token = "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJteVBheWxvYWREYXRhIjoxMjM0LCJpYXQiOjE2OTA4NzM4ODV9.YUmYY9aef9HOO8f2d6Umh2gtWRXJjDkzjm5FPhsQEA0";
const decodedValueByVerify = jwt.verify(token, "mysecretkey");
console.log(decodedValueByVerify); // { myPayloadData: 1234, iat: 1690873885 }
회고
나는 로그인의 인증 인가 세션이 어려운 개념이라는 걸
알고 있다. 그래서 강의와 강의자료를 여러번 복습해
개념을 제대로 정리하느라 시간을 많이 투자한 것 같다.
개념 복습도 좋지만 진도를 더 빼서 다음주 부터 시작 될
개인과제에 도움되는 짓을 해야되지 않았나 싶지만
제대로 이해하지 않으면 또 헤맬 것 같아서 두려웠나보다.
그래도 TIL 작성하면서 복습을 한 번 더 하니
낭낭하게 머리에 담기는 것 같다.
1주차를 완강했는데 머리가 복잡하다.
날잡고 한 번 제대로 복습 해야겠다.
제대로 살자.