반응형

Cursor를 계속 쓰다 보면, 굳이 에디터를 열지 않고도
터미널에서 바로 AI로 작업하고 싶을 때가 생긴다.

파일 하나 만들거나, 간단한 구조 잡는 정도는
CLI로 처리하는 게 더 빠르기 때문이다.

찾아보니 Cursor에도 CLI 형태의 에이전트가 따로 있어서
설치부터 사용까지 정리해봤다.


1. 설치 방법

설치는 한 줄이면 끝난다.

 
 

생각보다 별 과정 없이 바로 설치된다.
설치가 끝나면 터미널을 한 번 새로 열어주는 게 좋다.


2. 설치 확인

정상적으로 설치됐는지 확인하려면:

 
cursor-agent --version
 

버전 정보가 나오면 문제없이 설치된 상태다.


3. 로그인

처음 실행할 때는 로그인을 한 번 해줘야 한다.

 
cursor-agent login
 

명령어를 입력하면 브라우저가 열리고,
Cursor 계정으로 로그인하면 자동으로 연결된다.

이 과정도 꽤 간단한 편이다.


4. 기본 사용법

이제 원하는 프로젝트 폴더로 이동해서 실행하면 된다.

 
cd ~/project/Actune
cursor-agent
 

이렇게 실행하면 터미널에서 바로 대화형 모드로 들어간다.

Cursor 에디터에서 쓰던 것처럼 자연스럽게
명령을 입력하면 파일 생성이나 코드 수정이 가능하다.


5. 한 줄 명령으로 실행하기

대화형 모드 말고, 한 번만 실행하고 끝내는 것도 가능하다.

 
cursor-agent "이 폴더에 README 만들어줘"
 

이런 식으로 명령을 주면 바로 작업을 수행하고 종료된다.

간단한 작업에는 이 방식이 더 편하다.


6. 써보면서 느낀 점

실제로 써보면
“이걸 왜 이제 알았지?” 싶은 느낌이 든다.

특히 이런 상황에서 꽤 유용하다:

  • IDE 열기 귀찮을 때
  • 빠르게 파일 하나 만들고 싶을 때
  • 간단한 리팩토링이나 구조 잡을 때

터미널에서 바로 AI를 붙여서 쓸 수 있다는 점이
생각보다 작업 흐름을 많이 줄여준다.

반응형

AI가 코드를 작성하는 시대가 되었다.
이제 단순 구현 능력은 점점 중요도가 낮아지고 있다.

하지만 한 가지는 변하지 않는다.

무엇을 어떻게 만들 것인지 결정하는 능력, 즉 설계는 여전히 인간의 영역이다.

AI는 빠르게 코드를 만들어주지만,
그 코드가 올바른 구조인지, 미래에도 유지될 수 있는지 판단하지는 않는다.

결국 개발자의 역할은 바뀌고 있다.

  • 예전: 직접 구현하는 사람
  • 지금: 구조를 결정하고 검증하는 사람

이 글은 “설계를 잘하기 위해 무엇을 공부해야 하는가”를
단순 이론이 아니라 판단 기준을 만드는 과정으로 정리한 로드맵이다.


0. 설계란 무엇인가

설계는 코드를 잘 짜는 능력이 아니다.

설계는 다음 질문에 답할 수 있는 능력이다.

  • 이 구조는 왜 이렇게 나뉘어 있는가
  • 데이터는 어디서 생성되고 어디서 검증되는가
  • 장애가 발생하면 어디서 터지는가
  • 트래픽이 증가하면 무엇이 병목이 되는가

중요한 건 하나다.

설계는 현재가 아니라 미래를 기준으로 하는 판단이다.

따라서 CS 공부도 단순 지식 암기가 아니라
문제가 발생했을 때 올바른 선택을 할 수 있는 기준을 만드는 과정이어야 한다.


1단계: 요청과 데이터 흐름 이해

목표

하나의 요청이 시스템을 어떻게 통과하는지 명확히 설명할 수 있어야 한다.

핵심 개념

  • HTTP request/response lifecycle
  • REST API 설계
  • 동기 vs 비동기
  • blocking vs non-blocking
  • 직렬화/역직렬화 (JSON, DTO)

왜 중요한가

대부분의 설계 문제는 “흐름을 잘못 이해하는 것”에서 시작된다.

  • API 응답이 느린 이유
  • 스레드가 막히는 이유
  • 불필요한 네트워크 비용

흐름을 모르면 구조를 나눌 수 없다.

학습 방법

  • 하나의 API 요청을 끝까지 로그로 추적
  • Controller → Service → Repository 흐름 시각화
  • 요청 1건이 DB를 몇 번 호출하는지 확인

체크 기준

  • “이 API는 왜 동기인가?” 설명할 수 있는가
  • “비동기로 바꾸면 어떤 문제가 생기는가” 말할 수 있는가

2단계: 데이터 저장과 트랜잭션

목표

데이터가 깨지지 않도록 보호하는 구조를 설계할 수 있어야 한다.

핵심 개념

  • 트랜잭션 (ACID)
  • Isolation Level
  • 인덱스
  • N+1 문제
  • 정규화 vs 비정규화
  • Lock 전략

왜 중요한가

운영 환경에서 가장 많이 터지는 영역은 DB다.

  • 데이터 정합성 문제
  • 성능 저하
  • deadlock

이 영역을 이해하지 못하면
“동작하는 코드”는 만들 수 있어도
“신뢰할 수 있는 서비스”는 만들 수 없다.

학습 방법

  • 동일 기능을 다양한 쿼리로 구현해보기
  • 인덱스 적용 전/후 성능 비교
  • 트랜잭션 범위 줄이는 실험

체크 기준

  • “왜 이 쿼리에 인덱스가 필요한가” 설명 가능한가
  • “트랜잭션이 길어지면 어떤 문제가 생기는가” 말할 수 있는가

3단계: 객체 설계와 책임 분리

목표

코드를 기능이 아닌 책임 기준으로 나눌 수 있어야 한다.

핵심 개념

  • SRP (단일 책임 원칙)
  • 의존성 방향
  • 계층 구조
  • 도메인 모델링
  • 객체 간 협력

왜 중요한가

이 단계에서 개발자의 수준이 크게 갈린다.

  • 초급: 기능 중심 코드
  • 중급: 계층 중심 코드
  • 고급: 책임 중심 설계

설계가 좋은 시스템은 기능이 추가되어도 무너지지 않는다.

학습 방법

  • 기존 코드의 책임 위치 분석
  • 하나의 기능을 여러 구조로 설계
  • Controller 로직을 Domain으로 이동시켜보기

체크 기준

  • “이 로직은 왜 여기에 있는가” 설명 가능한가
  • “이 책임을 옮기면 어떤 장점이 생기는가” 말할 수 있는가

4단계: 비동기 처리와 시스템 확장

목표

트래픽이 증가해도 구조가 유지되도록 설계할 수 있어야 한다.

핵심 개념

  • 비동기 처리 (Future, Event)
  • 메시지 큐
  • 캐싱 전략
  • stateless vs stateful
  • eventual consistency

왜 중요한가

서비스는 항상 성장한다.

  • 트래픽 증가
  • 응답 속도 요구
  • 외부 시스템 연동

이때 기존 구조를 유지하면서 확장할 수 있어야 한다.

학습 방법

  • 동기 로직을 비동기로 변환
  • 캐시 적용 전/후 비교
  • 간단한 이벤트 기반 구조 구현

체크 기준

  • “비동기로 바꾸면 어떤 trade-off가 있는가”
  • “캐시 사용 시 정합성은 어떻게 보장할 것인가”

5단계: 장애 대응과 운영 설계

목표

문제가 발생했을 때 빠르게 원인을 찾고 복구할 수 있어야 한다.

핵심 개념

  • 로깅 전략
  • 모니터링 (metrics, tracing)
  • timeout / retry
  • circuit breaker
  • 장애 격리

왜 중요한가

실제 서비스에서는 “정상 동작”보다
“비정상 상황 대응”이 더 중요하다.

  • 외부 API 실패
  • DB 지연
  • 네트워크 장애

이 상황에서 시스템이 전체적으로 무너지지 않아야 한다.

학습 방법

  • 일부러 timeout 상황 만들기
  • 외부 API 실패 시뮬레이션
  • retry 로직 적용 후 영향 분석

체크 기준

  • “이 API가 실패하면 어떻게 동작하는가”
  • “장애 발생 시 어디를 먼저 봐야 하는가”

6단계: AI 시대의 설계 학습법

AI는 이제 코드를 대신 작성한다.
하지만 설계는 대신 해주지 않는다.

따라서 학습 방식도 바뀌어야 한다.

설계 질문을 먼저 던진다

코드를 작성하기 전에 항상 생각한다.

  • 이 책임은 어디에 있어야 하는가
  • 이 구조는 왜 이렇게 나뉘어 있는가
  • 어디가 병목이 될 가능성이 있는가
  • 트래픽이 증가하면 어디가 먼저 터지는가

하나의 기능을 여러 번 설계한다

  • 빠르게 구현하는 구조
  • 유지보수 중심 구조
  • 확장성 중심 구조

이 비교 과정에서 설계 감각이 생긴다.

AI를 구현자가 아닌 검증자로 사용한다

  • 설계 리뷰 요청
  • 리스크 분석 요청
  • 대안 비교 요청

AI를 잘 쓰는 개발자는
더 많은 코드를 만드는 사람이 아니라
더 많은 선택지를 검증하는 사람이다.


마무리

이제 구현은 점점 자동화되고 있다.
하지만 설계는 오히려 더 중요해지고 있다.

설계를 잘하는 개발자는 코드를 많이 작성하는 사람이 아니다.

문제가 발생하기 전에 어디서 터질지를 예측할 수 있는 사람이다.

CS 공부의 목적은 지식을 쌓는 것이 아니라
그 예측을 가능하게 하는 기준을 만드는 것이다.

결국 설계는 기술이 아니라 판단이다.

'컴퓨터 > 지식' 카테고리의 다른 글

Gmail SMTP 사용 방법  (1) 2025.04.28
반응형

토이 프로젝트나 초기 서비스 단계에서는 인프라를 크게 가져가기보다
VM 하나로 시작하는 경우가 많다.

이 글에서는 VM 1대로 서비스를 운영할 때 최소한으로 챙겨야 하는
보안 및 운영 설정을 정리했다.


전체 구조

초기 구성은 보통 다음과 같이 가져간다.

  • Nginx (외부 요청 처리)
  • 애플리케이션 서버 (내부 포트)
  • DB (로컬에서만 접근)

외부에서는 HTTP/HTTPS만 접근 가능하게 하고,
나머지는 모두 내부에서만 통신하도록 구성한다.


1. 자동 재시작 (systemd)

서버가 재부팅되거나 애플리케이션이 죽었을 때
자동으로 다시 실행되도록 설정해야 한다.

Linux 환경에서는 systemd를 사용하면 된다.

 
[Unit]
Description=my-app
After=network.target

[Service]
User=ubuntu
WorkingDirectory=/home/ubuntu/app
ExecStart=/usr/bin/java -jar app.jar
Restart=always
RestartSec=5

[Install]
WantedBy=multi-user.target
 

핵심은 Restart=always 옵션이다.
이 설정으로 장애 발생 시 자동 재시작이 가능하다.

또한 아래 명령어로 부팅 시 자동 실행되도록 설정한다.

 
systemctl enable my-app
 

2. DB 백업 (cron)

데이터 유실을 막기 위해 백업은 반드시 필요하다.
초기에는 하루 1회 자동 백업이면 충분하다.

예시 (MySQL 기준):

 
mysqldump -u USER -pPASSWORD DB_NAME > /backup/db_$(date +\%F).sql
 

crontab에 등록:

 
crontab -e
 
 
0 3 * * * mysqldump -u USER -pPASSWORD DB_NAME > /backup/db_$(date +\%F).sql
 

운영 시에는 다음을 같이 고려하는 것이 좋다.

  • 최근 7~14일치만 보관
  • 백업 파일을 외부 스토리지에도 저장
  • 실제 복구 테스트 1회 진행

3. 방화벽 설정

가장 중요한 원칙은 하나다.

필요한 포트만 열고 나머지는 모두 차단한다

외부에 열어야 하는 포트는 다음 정도면 충분하다.

  • 22 (SSH)
  • 80 (HTTP)
  • 443 (HTTPS)

앱 서버 포트(8080 등)와 DB 포트(3306 등)는
외부에서 접근할 수 없도록 막는다.

Ubuntu 기준으로는 ufw를 사용하면 간단하다.

 
sudo ufw allow 22
sudo ufw allow 80
sudo ufw allow 443
sudo ufw enable
 

이렇게 설정하면 외부에서는 웹 요청만 들어오고,
애플리케이션과 DB는 내부에서만 접근 가능하다.


4. SSL 적용 (HTTPS)

HTTPS는 이제 필수다.
가장 간단한 방법은 Let’s Encrypt를 사용하는 것이다.

 
sudo apt install certbot python3-certbot-nginx
sudo certbot --nginx -d example.com
 

이 과정에서 인증서가 자동으로 발급되고
Nginx 설정까지 함께 적용된다.

Let’s Encrypt 인증서는 90일마다 갱신이 필요하다.
자동 갱신이 설정되지만, 한 번 정도는 확인해보는 것이 좋다.

 
sudo certbot renew --dry-run
 

최종 구성 정리

초기 VM 1대 구성은 다음과 같이 정리할 수 있다.

  • Nginx: 80 / 443 포트 공개
  • 애플리케이션: 내부 포트에서 실행
  • DB: localhost에서만 접근
  • systemd: 자동 재시작
  • cron: DB 백업
  • ufw: 최소 포트만 허용
  • certbot: SSL 자동 갱신

우선순위

처음 세팅할 때는 아래 순서로 진행하는 것을 추천한다.

  1. Nginx 설정
  2. SSL 적용
  3. 방화벽 설정
  4. 애플리케이션 자동 실행
  5. DB 백업 자동화
  6. 백업 복구 테스트

마무리

초기 서비스에서는 완벽한 인프라보다
“문제 발생 시 복구 가능한 상태”를 만드는 것이 더 중요하다.

VM 하나로 시작하더라도
자동 재시작, 백업, 방화벽, SSL 이 네 가지만 제대로 설정하면
안정적으로 운영할 수 있다.


반응형

Claude CLI를 사용하다 보면 자연스럽게 드는 고민이 있다.
터미널을 새로 열어도 이전 대화의 흐름을 이어가고 싶다는 점이다.

하지만 모든 히스토리를 계속 유지하는 방식은 오히려 비효율적이다.
토큰이 불필요하게 커지고, 응답 품질도 떨어질 수 있기 때문이다.

그래서 기획 단계에서는 “히스토리를 유지”하기보다
생각을 정리해서 이어가는 방식이 더 적합하다.


기본 접근 방식

핵심은 하나다.

대화를 이어가는 것이 아니라, 정리된 컨텍스트를 다시 주입한다

이를 위해 간단한 파일 하나를 만든다.


컨텍스트 파일 만들기

프로젝트 루트에 아래와 같은 파일을 만든다.

 
.claude/idea.md
 

내용은 자유롭게 작성하되, 구조를 잡아두는 것이 좋다.

 
# 프로젝트 아이디어

## 목적
- 무엇을 만들려고 하는가

## 문제 정의
- 어떤 문제를 해결하는가

## 핵심 기능
- 기능 1
- 기능 2

## 현재 고민
- 이 방향이 맞는지
- 구조를 어떻게 가져갈지

## 다음 할 일
- 아이디어 정리
 

Claude CLI와 함께 사용하는 방법

작업을 시작할 때마다 이 파일을 함께 넘겨준다.

 
claude "$(cat .claude/idea.md)"
 

이렇게 하면 이전에 정리한 내용을 기반으로 대화를 이어갈 수 있다.


중요한 포인트

항상 모든 컨텍스트를 유지하려고 할 필요는 없다.

오히려 다음과 같은 방식이 더 효율적이다.

  • 필요할 때만 컨텍스트를 주입한다
  • 작업이 끝나면 내용을 정리한다
  • 정리된 내용만 다음에 이어서 사용한다

작업 후 정리 루틴

대화가 어느 정도 진행되면, 다음과 같이 정리를 요청한다.

 
claude "지금까지 논의된 내용을 기획 관점에서 정리해줘"
 

그리고 그 결과를 다시 idea.md에 반영한다.

이 과정을 반복하면 점점 더 정제된 기획 문서가 만들어진다.


구조 확장하기

아이디어가 커지면 파일을 나누는 것이 좋다.

 
.claude/
idea.md
architecture.md
api.md
ui.md
 

이렇게 분리하면 각 주제별로 필요한 컨텍스트만 선택해서 사용할 수 있다.


마무리

Claude CLI를 사용할 때 중요한 것은
모든 대화를 유지하는 것이 아니라, 의미 있는 정보만 남기는 것이다.

기획 단계에서는 특히 더 그렇다.


 

반응형

이전 글에서 Homebrew 설치를 마쳤다면,
이제 Node.js와 Claude CLI를 설치해서 실제 개발에 사용할 수 있는 환경을 만든다.

 


Node.js 설치

Homebrew를 이용하면 Node.js를 간단하게 설치할 수 있다.

 
brew install node
 

설치가 완료되면 아래 명령어로 확인한다.

 
node -v
npm -v
 

Node.js는 npm(Node Package Manager)을 포함하고 있기 때문에 별도로 npm을 설치할 필요는 없다.


Claude CLI 설치

Node.js가 설치되어 있다면 Claude CLI도 바로 설치할 수 있다.

 
npm install -g @anthropic-ai/claude-code
 

설치 후 아래 명령어로 실행한다.

 
claude
 

처음 실행 시 브라우저가 열리면서 로그인 과정을 진행하게 된다.


사용 방법

프로젝트 폴더에서 claude 명령어를 실행하면 CLI 기반으로 Claude를 사용할 수 있다.

 
cd my-project
claude
 

코드 생성이나 수정 요청을 바로 입력할 수 있다.


마무리

이제 기본적인 개발 환경이 준비되었다.
Homebrew → Node.js → Claude CLI 순으로 설치하면 대부분의 개발 작업을 바로 시작할 수 있다.


한 줄 정리

Node.js 설치 후 Claude CLI까지 연결하면 기본 개발 환경이 완성된다.


 

반응형

맥북을 새로 구매하면서 개발 환경을 다시 세팅하게 됐다.
가장 먼저 설치한 건 macOS용 패키지 매니저인 Homebrew다.


Homebrew란?

macOS에서 필요한 개발 도구를 쉽게 설치할 수 있게 해주는 패키지 매니저다.
Node.js, Git 같은 것들을 명령어 한 줄로 설치할 수 있다.


설치 방법

터미널을 열고 아래 명령어를 실행한다.

설치 과정에서 비밀번호 입력이 필요할 수 있다.


Apple Silicon(M1~M5) 추가 설정

M 시리즈 맥에서는 환경 변수 설정을 따로 해줘야 한다.

 
echo 'eval "$(/opt/homebrew/bin/brew shellenv)"' >> ~/.zprofile
eval "$(/opt/homebrew/bin/brew shellenv)"
 

이 과정을 해야 brew 명령어가 정상적으로 동작한다.


설치 확인

 
brew -v
 

버전 정보가 출력되면 정상적으로 설치된 것이다.


마무리

이제 다음과 같이 필요한 도구들을 설치하면 된다.

 
brew install node
brew install git
 
화이팅
반응형

JWT 인증에서 Access Token 자동 갱신 구현 (Axios 기반)

JWT 기반 인증을 사용할 때 Access Token은 일반적으로 짧은 만료 시간을 가집니다. 이는 보안을 강화하기 위한 전략이지만, 토큰이 만료될 때마다 사용자가 다시 로그인해야 한다면 UX는 매우 나빠지겠죠. 이를 해결하기 위해 Refresh Token을 이용한 자동 갱신 방식이 널리 사용됩니다.

이 글에서는 프론트엔드에서 Access Token이 만료되었을 때, 자동으로 /auth/refresh 엔드포인트를 호출해 토큰을 갱신하고 요청을 재시도하는 구현 방법을 설명합니다.

✅ 사용 기술: Axios + JWT + HttpOnly 쿠키 기반 인증


🎯 구현 목표

  1. API 요청 도중 Access Token이 만료되면 자동으로 /auth/refresh 호출
  2. 새 Access Token을 발급받고, 기존 실패한 요청을 재시도
  3. Refresh Token은 HttpOnly 쿠키에 저장되어 자동 포함됨
  4. Refresh 실패 시 로그아웃 처리

🔧 Axios 인스턴스 생성 및 인터셉터 설정

import axios from 'axios';

const api = axios.create({
  baseURL: 'https://your-api.com',
  withCredentials: true, // 쿠키 포함 필수 설정
});

let isRefreshing = false;
let failedQueue: any[] = [];

const processQueue = (error: any, token: string | null = null) => {
  failedQueue.forEach(prom => {
    if (error) prom.reject(error);
    else prom.resolve(token);
  });
  failedQueue = [];
};

api.interceptors.response.use(
  res => res,
  async err => {
    const originalRequest = err.config;

    if (err.response?.status === 401 && !originalRequest._retry) {
      if (isRefreshing) {
        return new Promise((resolve, reject) => {
          failedQueue.push({ resolve, reject });
        }).then(() => api(originalRequest));
      }

      originalRequest._retry = true;
      isRefreshing = true;

      try {
        await api.post('/auth/refresh'); // Refresh Token은 쿠키에 자동 포함됨
        processQueue(null);
        return api(originalRequest); // 실패한 요청 재시도
      } catch (refreshError) {
        processQueue(refreshError, null);
        window.location.href = '/login'; // 리프레시 실패 시 로그아웃 처리
        return Promise.reject(refreshError);
      } finally {
        isRefreshing = false;
      }
    }

    return Promise.reject(err);
  }
);

export default api;

🔁 흐름 정리

  1. 유저가 API 요청을 보냄
  2. 서버가 Access Token 만료로 401 Unauthorized 응답
  3. Axios 인터셉터가 이를 감지하고 /auth/refresh 호출
  4. Refresh Token은 HttpOnly 쿠키에 자동 포함됨
  5. 새 Access Token이 발급되면 원래 요청을 재시도
  6. Refresh 실패 시 로그인 페이지로 이동

✅ 보안 고려 사항

항목설명

withCredentials: true 쿠키를 요청에 포함하려면 반드시 설정
HttpOnly 쿠키 JS에서 토큰 접근 불가 → XSS 방어
SameSite=Strict 또는 Lax CSRF 방어용 쿠키 설정
Refresh Token 저장 위치 반드시 쿠키 (localStorage 금지)
Refresh 실패 시 처리 로그아웃 처리 or 알림 후 로그인 페이지 이동

🧠 마무리

Axios 인터셉터를 활용하면 토큰 갱신 로직을 모든 요청에 일관되게 적용할 수 있어, 보안과 UX 모두를 만족시키는 인증 흐름을 만들 수 있습니다.

'컴퓨터 > Java' 카테고리의 다른 글

쿠키(Cookie) 옵션 완벽 정리  (0) 2025.05.19
Spring @Transactional이 내부 메소드에서 안 먹는 이유와 해결법  (0) 2025.03.25
JAVA 21 변경점  (13) 2024.02.26
Java8 / Java 11 차이  (9) 2021.11.07
반응형

🔐 쿠키(Cookie) 옵션 완벽 정리: HttpOnly, Secure, SameSite의 모든 것

웹 개발에서 인증과 보안을 고민할 때 가장 먼저 마주치는 개념 중 하나가 바로 **쿠키(Cookie)**입니다. 하지만 쿠키 설정 시 등장하는 HttpOnly, Secure, SameSite 옵션이 정확히 뭘 의미하고, 어떤 보안 이슈를 막아주는지 확실하게 아는 사람은 많지 않습니다.

이 글에서는 실무에서 꼭 알아야 할 쿠키 옵션들의 기능, 보안 목적, 사용 예시를 정리해드릴게요.


🍪 쿠키란?

쿠키는 클라이언트(브라우저)에 저장되는 작은 데이터 조각입니다.

  • 서버가 Set-Cookie 헤더로 값을 내려주면,
  • 브라우저는 쿠키를 저장하고,
  • 이후 같은 도메인 요청마다 자동으로 쿠키를 전송합니다.

대표적인 활용 예:

  • 로그인 상태 유지 (세션 ID / JWT)
  • 장바구니 상태 저장
  • 사용자 설정 기억 (언어, 테마 등)

✅ 주요 쿠키 옵션 정리

옵션명설명방어하는 보안 위협
HttpOnly JS에서 쿠키 접근 불가 XSS (스크립트 탈취)
Secure HTTPS 연결에서만 전송 패킷 도청, MITM
SameSite 외부 요청 시 쿠키 전송 여부 제어 CSRF (요청 위조)
Path 특정 경로에만 쿠키 전송 제한된 범위 적용
Domain 서브도메인 공유 여부 도메인 스코프 설정
Max-Age / Expires 만료 시간 설정 자동 삭제
SameParty 제3자 쿠키 제한 회피 (실험적) Chrome Privacy Sandbox 대응
 

🔐 HttpOnly: JavaScript 접근 차단

Set-Cookie: token=abc123; HttpOnly
  • ✅ 쿠키를 JavaScript에서 document.cookie로 접근 불가
  • ✅ XSS 공격 시에도 쿠키를 훔칠 수 없음
  • ❌ JS로 토큰을 꺼내서 Authorization 헤더로 직접 보내야 하는 경우 사용 불가

💡 실무 팁: 인증 관련 쿠키(세션 ID, Access Token)는 반드시 HttpOnly 설정!


🔒 Secure: HTTPS에서만 전송

Set-Cookie: token=abc123; Secure
  • ✅ HTTPS 연결일 때만 서버로 쿠키 전송
  • ❌ HTTP 요청에는 전송되지 않음 (MITM 방지)
  • 📌 Secure이 없는 쿠키는 평문 HTTP 요청에 노출될 수 있음

💡 실무 팁: Secure 쿠키를 쓰려면 HTTPS 환경이 기본 전제입니다. 운영환경이라면 무조건 사용하세요.


🛡️ SameSite: CSRF 방어의 핵심

Set-Cookie: token=abc123; SameSite=Strict
값설명
Strict 다른 사이트에서 유입된 요청은 모두 쿠키 차단 (가장 안전)
Lax GET이나 a 링크, form 전송 등은 허용 / JS fetch 등은 차단
None 모든 외부 요청에 허용 (단, Secure 필수)
 

💡 실무 팁: 인증 관련 쿠키에는 보통 SameSite=Strict 또는 Lax를 설정합니다. None은 제3자 쿠키 용도로만 사용하세요.


📁 Path, Domain: 적용 범위 제어

Set-Cookie: theme=dark; Path=/settings
  • Path=/settings: /settings 이하에서만 전송
  • Domain=example.com: sub.example.com에서도 공유 가능

💡 실무 팁: 보안성 향상을 위해 불필요하게 넓은 범위는 피하세요.


⏰ Max-Age, Expires: 쿠키 수명

Set-Cookie: token=abc123; Max-Age=900
  • Max-Age=900: 900초(15분) 후 만료
  • Expires=Wed, 21 Oct 2025 07:28:00 GMT: 지정된 날짜/시간에 만료

설정이 없으면 세션 쿠키가 되어 브라우저 종료 시 삭제됩니다.


✅ 실무 예시: 로그인 쿠키 설정

Set-Cookie: access_token=eyJ...; HttpOnly; Secure; SameSite=Strict; Path=/; Max-Age=900
  • 🔐 JS 접근 불가 (HttpOnly)
  • 🔒 HTTPS 환경에서만 전송 (Secure)
  • 🛡️ CSRF 방지 (SameSite=Strict)
  • ⏰ 15분 후 자동 만료 (Max-Age)

🧠 마무리 요약

옵션설명권장 여부
HttpOnly JS 접근 차단 ✅ 항상 사용
Secure HTTPS에서만 전송 ✅ 운영환경 필수
SameSite 외부 요청 제한 ✅ CSRF 방어
Max-Age 유효 기간 설정 ✅ 필요시 사용
 

💬 마치며

쿠키는 단순한 저장소가 아니라, 보안 설정 하나로도 전체 서비스의 안정성을 좌우할 수 있는 민감한 요소입니다. 특히 인증과 세션 처리에 쿠키를 사용하는 경우에는 HttpOnly, Secure, SameSite는 사실상 필수 옵션이라고 생각하셔야 합니다.

보안은 구현보다 구성입니다.
조금만 신경 쓰면 더 안전한 서비스를 만들 수 있어요.

+ Recent posts