JWT 기반 세션과 Express-session 기반 세션 비교
JWT(JSON Web Token) 기반 세션과 Express-session 기반 세션은 각각의 인증 및 인가 방식으로 사용되며, 각기 다른 장단점을 가지고 있습니다. 두 방법을 비교하여 어떤 상황에서 어떤 방식이 더 적합한지 알아보겠습니다.
### 1. JWT 기반 세션
**장점:**
1. **무상태**:
- 서버는 클라이언트의 세션 상태를 유지할 필요가 없습니다. 토큰 자체에 모든 필요한 정보를 포함하기 때문에 확장성이 뛰어납니다.
- 여러 서버 간에 세션 상태를 공유할 필요가 없어 서버 확장이 용이합니다.
2. **유연성**:
- 다양한 클레임을 포함할 수 있어 사용자 정보와 권한을 손쉽게 관리할 수 있습니다.
- 클라이언트와 서버 간의 데이터 교환이 간편합니다.
3. **표준화**:
- 다양한 프로그래밍 언어와 플랫폼에서 쉽게 사용할 수 있습니다.
- OAuth, OpenID Connect 등의 표준을 준수합니다.
**단점:**
1. **보안 문제**:
- 토큰이 탈취되면 만료되기 전까지 악용될 수 있습니다. 따라서 짧은 만료 시간을 설정하고, 주기적으로 토큰을 갱신해야 합니다.
- 민감한 정보를 토큰에 직접 포함하면 위험할 수 있습니다.
2. **토큰 크기**:
- 토큰이 클수록 HTTP 헤더에 포함되어 전송되는 데이터 양이 많아집니다.
### 예제 코드 (JWT)
```javascript
const express = require('express');
const jwt = require('jsonwebtoken');
const app = express();
app.use(express.json());
const SECRET_KEY = 'your-secret-key';
// 로그인 엔드포인트
app.post('/login', (req, res) => {
const { username, password } = req.body;
// 유효성 검사 생략
const token = jwt.sign({ username }, SECRET_KEY, { expiresIn: '1h' });
res.json({ token });
});
// 보호된 엔드포인트
app.get('/protected', (req, res) => {
const token = req.headers['authorization'];
if (!token) {
return res.status(401).send('Access denied');
}
try {
const verified = jwt.verify(token, SECRET_KEY);
req.user = verified;
res.send('Protected content');
} catch (err) {
res.status(400).send('Invalid token');
}
});
app.listen(3000, () => {
console.log('Server running on port 3000');
});
```
### 2. Express-session 기반 세션
**장점:**
1. **보안**:
- 세션 ID만 클라이언트에 저장되며, 실제 사용자 정보는 서버 측에 저장되므로 민감한 정보가 노출되지 않습니다.
- 세션 데이터가 서버 측에 저장되므로, 세션 탈취의 위험이 줄어듭니다.
2. **세션 관리**:
- 세션 만료 및 삭제가 서버 측에서 관리되므로, 더 세밀한 세션 관리를 할 수 있습니다.
- 다양한 세션 저장소(redis, database 등)를 통해 세션 데이터를 유지할 수 있습니다.
**단점:**
1. **상태 유지**:
- 서버는 클라이언트의 세션 상태를 유지해야 합니다. 이는 서버 확장성을 저하시킬 수 있습니다.
- 서버 간 세션 데이터 공유가 필요할 경우 추가적인 설정이 필요합니다.
2. **부하 증가**:
- 서버에 세션 데이터를 저장하기 때문에 세션 관리에 대한 부하가 서버에 추가됩니다.
### 예제 코드 (Express-session)
```javascript
const express = require('express');
const session = require('express-session');
const app = express();
app.use(session({
secret: 'your-secret-key',
resave: false,
saveUninitialized: true,
cookie: { secure: true } // HTTPS 사용 시 true로 설정
}));
// 로그인 엔드포인트
app.post('/login', (req, res) => {
// 유효성 검사 생략
req.session.user = { username: req.body.username };
res.send('Logged in');
});
// 보호된 엔드포인트
app.get('/protected', (req, res) => {
if (!req.session.user) {
return res.status(401).send('Access denied');
}
res.send('Protected content');
});
app.listen(3000, () => {
console.log('Server running on port 3000');
});
```
### 비교 요약
| 항목 | JWT 기반 세션 | Express-session 기반 세션 |
| --- | --- | --- |
| **상태 관리** | 무상태 | 상태 유지 |
| **확장성** | 뛰어남 | 제한적 |
| **보안** | 토큰 탈취 시 위험 | 세션 ID 탈취 시 위험 |
| **유연성** | 클레임 포함 가능 | 제한적 |
| **서버 부하** | 낮음 | 높음 |
| **토큰 크기** | 클 수 있음 | 작음 |
### 결론
- **JWT**: 서버 확장이 필요한 분산 시스템, 마이크로서비스 아키텍처, 클라이언트와 서버 간의 빈번한 통신이 필요한 경우 적합합니다.
- **Express-session**: 보안이 최우선이고 서버 확장이 큰 문제가 되지 않으며, 상태 유지를 통해 더 세밀한 세션 관리를 원할 때 적합합니다.
각 방법의 장단점을 고려하여 프로젝트의 요구사항에 맞는 인증 방식을 선택하는 것이 중요합니다.