API 보안은 REST/GraphQL API를 무단 접근, 데이터 유출, 남용으로부터 보호하는 기술과 패턴의 총체다. OWASP API Security Top 10을 기준으로 인증, 인가, 입력 검증, 속도 제한 등을 구현해야 한다.
OWASP API Security Top 10 (2023)
| 순위 | 위협 | 대응 |
|---|
| API1 | 객체 수준 인가 결함 | 리소스별 소유권 검증 |
| API2 | 인증 결함 | JWT + 강력한 비밀 |
| API3 | 객체 속성 인가 결함 | 응답 필드 화이트리스트 |
| API4 | 무제한 리소스 소비 | Rate limiting, 페이지네이션 |
| API5 | 기능 수준 인가 결함 | RBAC 구현 |
JWT 인증 구현
javascript
const jwt = require('jsonwebtoken');
// 토큰 발급
app.post('/auth/login', async (req, res) => {
const user = await validateCredentials(req.body);
if (!user) return res.status(401).json({ error: 'Invalid credentials' });
const accessToken = jwt.sign(
{ userId: user.id, role: user.role },
process.env.JWT_SECRET,
{ expiresIn: '15m' } // 짧은 만료 시간
);
const refreshToken = jwt.sign({ userId: user.id }, process.env.REFRESH_SECRET, { expiresIn: '7d' });
res.json({ accessToken, refreshToken });
});
// 미들웨어
function authenticate(req, res, next) {
const token = req.headers.authorization?.split(' ')[1];
if (!token) return res.status(401).json({ error: 'No token' });
try {
req.user = jwt.verify(token, process.env.JWT_SECRET);
next();
} catch {
res.status(401).json({ error: 'Invalid token' });
}
}
Rate Limiting
javascript
const rateLimit = require('express-rate-limit');
const RedisStore = require('rate-limit-redis');
const apiLimiter = rateLimit({
windowMs: 15 * 60 * 1000, // 15분
max: 100,
store: new RedisStore({ sendCommand: (...args) => redisClient.sendCommand(args) }),
standardHeaders: true,
message: { error: 'Too many requests' },
});
app.use('/api/', apiLimiter);
관련 개념