본문 바로가기
개발&프로그래밍

[HTTP] 쿠키와 세션 완벽 가이드: 웹 인증의 기본

by 재아군 2025. 2. 20.

쿠키와 세션 완벽 가이드

쿠키(Cookie)란?

쿠키는 웹사이트가 사용자의 브라우저에 저장하는 작은 텍스트 파일입니다. 웹사이트는 쿠키를 통해 사용자의 설정이나 선호도를 기억할 수 있습니다.

 

쿠키의 주요 특징

  • 클라이언트(브라우저) 측에 저장
  • 만료 기간 설정 가능
  • 도메인별로 저장되어 관리
  • 용량 제한 있음 (보통 4KB)

 

쿠키 생성 예제 (Express)

app.get('/set-cookie', (req, res) => {
    res.cookie('user', 'john', {
        maxAge: 24 * 60 * 60 * 1000, // 24시간
        httpOnly: true,              // JS 접근 방지
        secure: true,               // HTTPS에서만 전송
        sameSite: 'strict'          // CSRF 방지
    });
    res.send('쿠키가 설정되었습니다.');
});

쿠키 조회

app.get('/get-cookie', (req, res) => {
    const userCookie = req.cookies.user;
    res.send(`사용자 쿠키: ${userCookie}`);
});

 

세션(Session)이란?

세션은 서버에 저장되는 사용자별 정보입니다. 클라이언트는 세션 ID만 가지고 있고, 실제 데이터는 서버에서 관리합니다.

 

세션의 주요 특징

  • 서버 측에 저장
  • 메모리 또는 데이터베이스에 저장
  • 보안성이 쿠키보다 높음
  • 서버 자원을 사용

 

세션 구현 예제 (Express)

const session = require('express-session');

app.use(session({
    secret: 'your-secret-key',
    resave: false,
    saveUninitialized: true,
    cookie: {
        secure: true,
        httpOnly: true,
        maxAge: 24 * 60 * 60 * 1000
    }
}));

// 세션 저장
app.post('/login', (req, res) => {
    const { username, password } = req.body;

    // 로그인 검증 후
    req.session.user = {
        id: 1,
        username: username,
        isLoggedIn: true
    };

    res.send('로그인 성공');
});

// 세션 확인
app.get('/profile', (req, res) => {
    if (req.session.user) {
        res.send(`안녕하세요, ${req.session.user.username}님`);
    } else {
        res.status(401).send('로그인이 필요합니다.');
    }
});

 

쿠키와 세션의 차이점

 

저장 위치

  • 쿠키: 클라이언트
  • 세션: 서버

 

보안성

  • 쿠키: 클라이언트에서 확인 가능
  • 세션: 클라이언트에서 확인 불가

 

리소스

  • 쿠키: 클라이언트의 리소스 사용
  • 세션: 서버의 리소스 사용

 

용량 제한

  • 쿠키: 약 4KB
  • 세션: 서버 환경에 따라 다름

 

보안 고려사항

 

쿠키 보안

  1. httpOnly 플래그
    res.cookie('auth', token, { httpOnly: true });
  2. secure 플래그
    res.cookie('auth', token, { secure: true });
  3. sameSite 설정
    res.cookie('auth', token, { sameSite: 'strict' });

 

세션 보안

세션 ID 관리

app.use(session({
    secret: process.env.SESSION_SECRET,
    name: 'sessionId',    // 기본 connect.sid 변경
    rolling: true,        // 요청마다 만료시간 갱신
    resave: false,
    saveUninitialized: false
}));

 

세션 탈취 방지

// 세션 재생성
app.post('/login', (req, res) => {
    req.session.regenerate((err) => {
        if (err) next(err);
        req.session.user = user;
        res.redirect('/');
    });
});

 

 

실제 구현 시나리오

로그인 구현

app.post('/login', async (req, res) => {
    const { username, password } = req.body;

    try {
        const user = await User.findOne({ username });
        const valid = await bcrypt.compare(password, user.password);

        if (valid) {
            req.session.user = {
                id: user.id,
                username: user.username
            };
            res.redirect('/dashboard');
        } else {
            res.status(401).send('로그인 실패');
        }
    } catch (error) {
        res.status(500).send('서버 오류');
    }
});

 

로그아웃 구현

app.post('/logout', (req, res) => {
    req.session.destroy((err) => {
        if (err) {
            return res.status(500).send('로그아웃 실패');
        }
        res.clearCookie('connect.sid');
        res.redirect('/login');
    });
});

 

인증 미들웨어

const authMiddleware = (req, res, next) => {
    if (req.session && req.session.user) {
        next();
    } else {
        res.status(401).redirect('/login');
    }
};

// 미들웨어 사용
app.get('/dashboard', authMiddleware, (req, res) => {
    res.render('dashboard', { user: req.session.user });
});

 

 

성능 최적화

  1. 세션 저장소 선택 
  2. const RedisStore = require('connect-redis').default; const redis = require('redis'); const redisClient = redis.createClient(); app.use(session({ store: new RedisStore({ client: redisClient }), secret: 'your-secret-key' }));

 

 

  1. 쿠키 크기 최적화
  • 필요한 정보만 저장
  • 만료 기간 적절히 설정

 

 

댓글