본문 바로가기
내일배움캠프_게임서버(202410)/분반 수업 Basic-A

숙제하기 - 6주차 인증 (Session / Cookie / JWT)

by GREEN나무 2024. 12. 24.
728x90

 

인증 (Authentication) : ‘로그인을 통해 서비스를 이용하는 것

회원가입, 로그인 등

서버 개발자가 인증에 대한 내용을 구현할 때에는 ‘Session’, ‘Cookie’, ‘JWT’에 대해 잘 알고 있어야 한다.

 

 

Session

서버에서 인증 데이터를 관리함

 

Session이 작동하는 방식

1. 사용자가 웹사이트에 접속합니다.

2. 그때 서버‘session id’라는 고유 번호를 만들어요. 사용자 고유 번호표라고 생각하면 편해요.

3. 그리고 이 session id쿠키에 담아서 브라우저(클라이언트)에 보내. (쿠키는 조금 뒤에 다시 볼게요.)

4. 브라우저는 이 session id를 내부 어딘가에 저장해요.

5. 이제 사용자가 서버에 무언가를 요청하면 자동으로 브라우저가 이 session id를 함께 서버에 보내.

6. 서버는 함께 들어온 session id를 기반으로 누가 이 요청을 보낸 것인지 판단할 수 있는거죠.

 

import express from 'express';

import session from 'express-session';

const app = express();

 

// 세션 설정

app.use(session({

secret: '나만의 비밀키', // 암호화 키

resave: false, // 세션이 변경되지 않으면 저장 안 함

saveUninitialized: true // 초기화되지 않은 세션도 저장

}));

 

// 로그인

app.get('/login', (req, res) => {

req.session.user = { name: '곰돌이' }; // 세션에 사용자 정보 저장

console.log(`Session ID: ${req.sessionID}`);

res.send('로그인 완료! 안녕하세요, 곰돌이님!');

});

 

// 사용자가 로그인 상태인지 확인

app.get('/check', (req, res) => {

console.log(`Session ID: ${req.sessionID}`); // 현재 요청의 세션 ID 출력

if (req.session.user) {

res.send(`환영합니다, ${req.session.user.name}!`);

} else {

res.send('로그인이 필요합니다!');

}

});

 

// 로그아웃

app.get('/logout', (req, res) => {

console.log(`Session ID (before destroy): ${req.sessionID}`); // 세션 삭제 전 ID 출력

req.session.destroy(() => { // 세션 삭제

res.send('로그아웃 완료!');

});

});

 

app.listen(3000, () => console.log('서버가 실행 중이에요!'));

 

브라우저와 논-브라우저

브라우저가 자동으로 쿠키를 보관해주는 것이기 때문에

브라우저가 아닌 곳(터미널에서)에서 로그인하면 쿠키가 저장안됨

터미널 예시

curl localhost:3000/login -v

쿠키

사용자 브라우저에 강제로 저장됨(보통 4Kb 이하의 아주 작은 데이터를 저장)

자동으로 번호표가 포함되어 요청함

사용자가 서버와 통신을 할 때 Cookie가 자동으로 서버에 전달되어요.

만료시간 지정 가능(만료 후 크키 사라짐. 재발급 받아야 함)

 

단점. 다른브라우저, 브라우저가 아닌 경우 사용하지 못함.

 

Cookie가 작동하는 방식

1. 사용자가 웹사이트에 접속합니다.

2. 서버가 사용자 브라우저에 저장하고 싶은 정보를 cookie로 만들어 브라우저에게 보냅니다.

3. 브라우저는 이 cookie를 저장합니다.(자동)

4. 사용자가 웹사이트에 다시 접속하면 브라우저가 자동으로 이 cookie를 서버에 보냅니다.

5. 서버는 이 cookie에 담겨있는 정보를 확인합니다.

 

import express from 'express';

import cookieParser from 'cookie-parser'; // 쿠키 파싱 미들웨어

const app = express();

 

// cookie-parser 미들웨어 등록

app.use(cookieParser());

 

// Cookie를 설정하는 예제

// 쿠키패서

app.get('/set-cookie', (req, res) => {

res.cookie('user', '곰돌이', { maxAge: 1000 * 60 * 60 }); // 1시간 동안 유지

res.send('Cookie가 설정되었습니다!');

});

 

// Cookie를 확인하는 예제

app.get('/get-cookie', (req, res) => {

console.log(req.cookie, req.cookies);

const userCookie = req.cookies['user'];

if (userCookie) {

res.send(`환영합니다, ${userCookie}!`);

} else {

res.send('Cookie가 없네요.');

}

});

 

// Cookie를 삭제하는 예제

// 서버한테 지워달라 요청

app.get('/delete-cookie', (req, res) => {

res.clearCookie('user'); // Cookie 삭제

res.send('Cookie가 삭제되었습니다!');

});

 

app.listen(3000, () => console.log('서버가 실행 중입니다!'));

 

 

 

JWT !!!!!!! 중요!!!!!!!!!(쿠키도 중요)

JWT (JSON Web Token)

JWT는 인터넷에서 안전하게 데이터를 주고받기 위해 사용하는 토큰입니다.

토큰은 데이터가 암호화되어 포함된 일종의 정보 덩어리로 생각할 수 있어요.

주로 인증(로그인)과 권한 부여(Authorization)에 사용됩니다.

 

자체가 티켓

JWT는 디지털 티켓 같은 거예요.

 

이 입장권에는 크게 3가지 정보가 들어가있다고 볼 수 있어요.

이게 입장권이라는 정보 (입장권 종류)

유저에 대한 정보 (이름, 입장권 번호, 입장권 날짜 등)

위조 방지 QR (직원이 이 입장권이 진짜인지 확인하는 방법)

 

import express from 'express';

import jwt from 'jsonwebtoken';

const app = express();

 

const SECRET_KEY = 'mySecretKey'; // JWT 생성에 사용할 비밀 키

 

// 1. 로그인: JWT 생성

app.get('/login', (req, res) => {

const user = { id: 123, name: '곰돌이' }; // 사용자 정보

const token = jwt.sign( // jwt.sign : 이걸 jwt로 만들겠다

user,

SECRET_KEY,

{ expiresIn: '1h' } // 1시간 유효

);

res.json({ token }); // JWT를 브라우저에 전달

});

 

// 2. 인증된 사용자만 접근

app.get('/dashboard', (req, res) => {

const token = req.headers['authorization']; // 요청 헤더에서 JWT 가져옴

if (!token) return res.status(401).send('로그인이 필요합니다!');

 

jwt.verify(token, SECRET_KEY, (err, decoded) => {

if (err) return res.status(403).send('유효하지 않은 토큰입니다.');

res.send(`환영합니다, ${decoded.name}!`);

});

});

 

app.listen(3000, () => console.log('서버 실행 중!'));

 

 

받은 jwt 읽기

eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpZCI6MTIzLCJuYW1lIjoi6rOw64-M7J20IiwiaWF0IjoxNzM0MjcwMjY1LCJleHAiOjE3MzQyNzM4NjV9.-sbQOCTXmQ5lnQ3eXx07-dOJici5KO01_a4CX8Sc1wo

 

뭐하는 입장권이냐.나에대한 정보.유효한 입장권임.유효시간

 

읽기

https://jwt.io/

HEADER:ALGORITHM & TOKEN TYPE

 

{

"alg": "HS256",

"typ": "JWT"

}

 

 

PAYLOAD:DATA

 

{

"id": 123,

"name": "곰돌이",

"iat": 1734270265,

"exp": 1734273865

}

 

 

VERIFY SIGNATURE

 

HMACSHA256(

base64UrlEncode(header) + "." +

base64UrlEncode(payload),

 

your-256-bit-secret

 

) secret base64 encoded

 

 

 

header, payload, signature

header- 토근 유형 알고리즘

payload - 내가 넣은 정보

signature - 헤더 페이로드를 결합 하고 비밀키를 사용하여 생성된 서명

 

실전

쿠키랑 같이 사용

JWT & Cookie:

유저가 서버에 어떤 정보를 요청합니다.

서버는 데이터베이스를 확인하고 해당 유저의 정보를 담은 JWT를 만듧니다.

JWTcookie로 만들어 브라우저에 저장합니다.

유저가 서버에 다시 요청을 보낼 때에 JWTCookie에 담겨 서버로 전달됩니다.

서버는 JWT를 확인해보면 유저의 정보를 바로 알 수 있습니다.

JWT를 쿠키에 저장하고, 브라우저가 요청할 때 자동으로 쿠키를 서버로 보냄.

Cookie 없이 사용

JWT & Header:

유저가 서버에 어떤 정보를 요청합니다.

서버는 데이터베이스를 확인하고 해당 유저의 정보를 담은 JWT를 만듧니다.

JWT를 그대로 유저에게 전달합니다.

유저는 그 JWTrequest header에 담아 서버에 전달합니다.

서버는 JWT를 확인해보면 유저의 정보를 바로 알 수 있습니다.

JWTHTTP 헤더에 넣어서 서버로 전달.

주로 Authorization 헤더에 “Bearer [JWT]” 형식으로 보냄.


분반

헤더 토큰 사용 및 세션 관리: 관련사항 정리

1. 토큰 관리 및 인증 흐름

  • 모바일 등 클라이언트는 요청 시 토큰을 헤더에 포함하여 인증.
  • 레디스는 세션 관리 도구로 사용되며, 토큰을 저장하고 만료 시간까지 유효성을 보장.
  • 로그아웃 처리:
    • 로그아웃 요청이 오면, 레디스에서 해당 토큰을 삭제하여 세션 무효화.
  • 단일 토큰 사용:
    • Access Token, Refresh Token을 나누지 않고, 하나의 토큰으로 모든 처리를 통합.

2. 레디스와 세션 정보 관리

  • 레디스 역할:
    • 세션 데이터 저장: 유저 정보를 캐싱하여 빠른 인증 및 상태 확인 가능.
    • 입장 상태 등 특정 정보 관리 가능.
  • 입장 상태 관리:
    • 사용자가 "입장했다"는 정보를 세션(또는 레디스)에 저장하여 추적 가능.
  • 로그아웃 시 세션 초기화:
    • 로그아웃 요청 시 레디스의 해당 데이터 삭제.

3. JWT 대체 및 설계 간소화

  • JWT를 사용할 수 있으나 현재 설계에서는 필요하지 않음.
    • 이유: 레디스를 활용해 유저 정보를 효율적으로 관리 가능.
    • 토큰 검증 및 상태 추적이 레디스를 통해 처리되므로 JWT의 장점(서버리스 인증)을 활용할 필요가 적음.

4. 로그아웃 여부에 따른 관리 방식

  • 로그아웃이 있는 경우:
    • 사용자가 명시적으로 로그아웃을 요청하면, 레디스에서 세션 삭제.
    • 즉, 해당 사용자의 인증 정보가 무효화됨.
  • 로그아웃이 없는 경우:
    • Access Token, Refresh Token 구조를 통해 자동 만료 또는 갱신으로 세션 관리 가능.

설계의 주요 포인트

  1. 레디스 기반 단일 토큰 관리: 단일 토큰으로 인증, 상태 추적, 로그아웃 처리 모두 가능.
  2. 간단하고 확장 가능한 구조: JWT 없이도 레디스를 통해 유저 정보와 상태를 효과적으로 관리.
  3. 상태 추적: 입장 여부 등 사용자 상태를 세션 데이터에 포함하여 필요 시 참조 가능.

 

시크릿키는 .env에 있어야함


숙제

 


 

 

https://teamsparta.notion.site/6-Session-Cookie-JWT-406ff7818f6c4f39829a8649cf395446#61a2a23586074c83b603b67249726408

 

 

 

숙제하기