복잡한 로그인 세션 없이도 안전하고 유연한 인증 시스템을 구축하고 싶으신가요? Express와 JWT로 가능한 이유를 알려드립니다.
안녕하세요, 오늘은 실제 프로젝트에서 자주 활용되는 Express 기반 JWT 인증 시스템의 전체 흐름을 정리해 보려 합니다. 기존의 세션 기반 인증은 유지 관리와 확장성 측면에서 많은 한계를 드러내곤 했는데요, JWT(Json Web Token)는 그런 점을 효율적으로 해결해줍니다. 최근 제가 API 서버와 React 프론트엔드를 분리하면서 적용했던 구조와 실무 경험을 바탕으로, 여러분께 실용적이면서도 깊이 있는 정보를 제공해드릴게요.
📌 바로가기 목차
1. JWT 인증이란? 전통적인 인증 방식과의 비교
JWT(Json Web Token)는 서버가 사용자 인증 후 발급한 토큰에 사용자의 정보를 담아 클라이언트에 전달하고, 이후 요청마다 해
당 토큰을 헤더에 포함해 인증하는 방식입니다. 기존의 세션 방식과는 다르게 서버는 인증 상태를 저장하지 않기 때문에, 무상태(stateless)로 작동합니다. 이는 서버 확장성에 유리하며, 모바일 및 SPA 환경에서 특히 효과적입니다.
한편, 세션 방식은 서버에 인증 정보를 저장하고 쿠키를 통해 사용자와 연결하는 방식으로, 유지 관리 및 서버 부하 측면에서 단점이 존재합니다. 다음 테이블은 두 방식의 주요 차이점을 정리한 것입니다.
항목 | 세션 기반 인증 | JWT 기반 인증 |
---|---|---|
상태 관리 | 서버에 세션 저장 | 서버 무상태 |
확장성 | 낮음 | 높음 |
인증 저장 위치 | 서버 메모리 | 클라이언트 토큰 |
2. Express 프로젝트에 JWT 적용하는 기본 방법
Express에서 JWT를 적용하려면 먼저 jsonwebtoken
패키지를 설치한 후, 로그인 시 JWT를 발급하고, 이후 요청에서 토큰을 해석하여 인증 처리하는 구조를 구현해야 합니다.
JWT는 보통 access token
과 refresh token
두 가지로 나누어 관리합니다. access token은 API 인증에 쓰이며, 만료 시간이 짧습니다. 반면 refresh token은 access token을 갱신할 때 사용되며, 서버나 DB에서 별도 저장하는 것이 일반적입니다.
3. 액세스 토큰 vs 리프레시 토큰 흐름 정리
JWT를 실무에서 사용하면 토큰을 두 가지로 나누는 패턴을 자주 접하게 됩니다. 아래는 그 흐름을 단계별로 정리한 체크리스트입니다.
- 사용자가 로그인 → 서버는 access + refresh token 발급
- access token → 클라이언트 저장(localStorage 등)
- refresh token → 서버 DB 또는 httpOnly cookie에 저장
- access token 만료 시 → refresh token으로 재발급
- refresh token 만료 시 → 로그인 재요청
이러한 구조를 구현하면 사용자가 로그아웃하지 않고도 일정 시간 동안 인증 상태를 유지할 수 있으며, 보안성도 강화됩니다. 단, refresh token은 서버에서 반드시 안전하게 관리되어야 합니다.
4. 사용자 인증 미들웨어 구현과 역할
Express에서 사용자 인증을 효율적으로 처리하려면 JWT 토큰 검증용 미들웨어를 만들어야 합니다. 이 미들웨어는 요청의 헤더에 포함된 access token을 검사하고, 유효하다면 사용자 정보를 req.user
에 삽입하여 이후 라우터에서 활용할 수 있게 합니다.
const jwt = require('jsonwebtoken');
function authMiddleware(req, res, next) {
const authHeader = req.headers['authorization'];
const token = authHeader && authHeader.split(' ')[1];
if (!token) return res.status(401).json({ message: 'Access token missing' });
try {
const user = jwt.verify(token, process.env.ACCESS_SECRET);
req.user = user;
next();
} catch (err) {
return res.status(403).json({ message: 'Invalid or expired token' });
}
}
이처럼 미들웨어 기반으로 인증을 처리하면 코드의 재사용성과 가독성이 높아지고, 인증이 필요한 API에서 간결하게 authMiddleware
만 삽입하면 됩니다.
5. JWT 보안 이슈와 실무 대응 팁
JWT는 편리한 인증 방식이지만, 다음과 같은 보안 이슈에 취약할 수 있으므로 실무에서는 반드시 다음 사항들을 고려해야 합니다.
- 토큰 탈취 방지: https + httpOnly cookie 사용
- 짧은 access token 수명 설정 (예: 15분)
- refresh token은 DB에 저장하고 블랙리스트 관리
- 토큰 서명 키는 .env에 저장하고 절대 공개하지 않기
6. 실무 구조 예시로 보는 API 인증 시스템 구성
마지막으로, JWT 기반 인증 시스템의 실무 아키텍처 예시를 소개합니다. 프론트엔드는 React, 백엔드는 Express를 사용하며, 로그인부터 인증, 갱신, 로그아웃까지 전반 흐름은 다음과 같습니다:
- 1️⃣ 로그인 요청 → 서버에서 access + refresh token 발급
- 2️⃣ access token: localStorage 저장 → API 요청 시 Authorization 헤더 사용
- 3️⃣ refresh token: 서버 DB에 저장 (userId 매핑)
- 4️⃣ access token 만료 시 → refresh token으로 /token/refresh 요청
- 5️⃣ 로그아웃 시 refresh token 삭제 → access token 무효화
이 구조는 보안성과 유지보수 측면에서 안정적이며, 현재 대부분의 SPA 백엔드 인증 구조에서 채택되고 있습니다.
7. 자주 묻는 질문 (FAQ)
JWT가 탈취되면 해당 사용자가 아닌 사람이 인증된 사용자처럼 행동할 수 있습니다. 따라서 https
사용, httpOnly cookie
저장, 짧은 만료 시간
설정이 매우 중요합니다.
access token은 짧게, refresh token은 길게 만료 시간을 설정함으로써 보안성과 편의성을 모두 확보할 수 있습니다. refresh token은 서버에서만 관리해 토큰 재발급 시에도 안전성을 유지합니다.
가능은 하지만 refresh token을 안전하게 관리하려면 DB 또는 Redis 같은 저장소는 필요합니다. 특히 로그아웃 처리나 강제 만료 등에서는 서버 상태 정보가 필요하므로 DB 연동이 일반적입니다.
Express에서 JWT를 활용한 인증 시스템은 빠르게 확장 가능한 API 서버를 구축하기 위한 핵심 기술 중 하나입니다. 이번 포스팅에서는 기본 개념부터 실무 적용, 보안 팁까지 전반적인 흐름을 정리해 보았습니다. 꼭 하나하나 구현해 보시면서 자신만의 인증 미들웨어 구조도 설계해보시길 추천드립니다. 인증 흐름을 정확히 이해하면 더 이상 "로그인 로직"은 어렵지 않습니다.
'SW프로래밍 개발 > Javascript' 카테고리의 다른 글
Express.js를 활용한 RESTful API 구축 및 미들웨어 적용 방법 (0) | 2025.04.15 |
---|---|
Node.js란? 개념부터 프로젝트 적용까지 한 번에 이해하기 (2025년에도 선택되는 이유) (1) | 2025.04.15 |
React + TypeScript로 안전한 프론트엔드 개발하기 (1) | 2025.04.14 |
자바스크립트 기초 마스터 후 다음 단계는? ES6, React로 나아가기 (1) | 2025.04.12 |