RESTful API와 마이크로서비스 시대에서 엔드포인트를 보호하는 것은 절대적으로 필수적입니다. 특정 리소스에 접근할 수 있는 사용자가 인증된 사용자인지 확인하기 위한 인기있고 효과적인 방법 중 하나는 Bearer Token 인증을 사용하는 것입니다. 이 블로그에서는 Express를 사용하여 Node.js 애플리케이션에서 Bearer Token 인증을 구현하는 방법을 살펴보겠습니다. Bearer Token의 기초, 애플리케이션에 설정하는 방법, 강력한 보안 아키텍처를 보장하기 위한 모범 사례를 다룰 것입니다.
Bearer Token 인증이란 무엇인가요?
Bearer Token 인증은 사용자 인증 시 토큰을 발급하며, 클라이언트는 이후 요청의 Authorization 헤더에 이를 포함해야 합니다. 이 토큰은 자격 증명의 "소지자" 역할을 하며, 즉 이 토큰을 가진 누구나 관련 리소스에 접근할 수 있습니다. JSON Web Tokens (JWT)는 상태 비저장 특성과 유연성 덕분에 일반적으로 사용되는 Bearer Token의 형태입니다.
1단계: Node.js와 Express 애플리케이션 설정하기
Bearer Token 구현에 들어가기 전에, 기본 Node.js와 Express 애플리케이션을 설정해보겠습니다. 새로운 프로젝트를 초기화하고 필요한 종속성을 설치하는 것부터 시작하겠습니다.
1. 새로운 프로젝트 초기화:
mkdir express-bearer-token && cd express-bearer-token
npm init -y
2. 필요한 패키지 설치:
npm install express body-parser jsonwebtoken
express
: Node.js의 웹 프레임워크입니다.jsonwebtoken
: JWT를 서명, 검증 및 디코딩하는 라이브러리입니다.body-parser
: 들어오는 요청 본문을 파싱하는 미들웨어입니다.
3. 기본 서버 설정:
index.js
파일을 생성하고 Express 서버를 설정합니다:
const express = require('express');
const bodyParser = require('body-parser');
const jwt = require('jsonwebtoken');
const app = express();
const PORT = 3000;
const SECRET_KEY = 'your_secret_key';
app.use(bodyParser.json());
app.get('/', (req, res) => {
res.send('Bearer Token 인증 튜토리얼에 오신 것을 환영합니다!');
});
app.listen(PORT, () => {
console.log(`서버가 http://localhost:${PORT}에서 실행되고 있습니다.`);
});
2단계: JWT 생성하기
우선, JWT 토큰을 생성하고 다시 보내기 위한 사용자 로그인 엔드포인트를 만들어야 합니다. 간단하게 하기 위해 더미 사용자를 사용할 것입니다.
1. 로그인 경로 추가:
const users = {
user1: { username: 'user1', password: 'password1' } // 더미 사용자
};
app.post('/login', (req, res) => {
const { username, password } = req.body;
const user = users[username];
if (user && user.password === password) {
const token = jwt.sign({ username }, SECRET_KEY, { expiresIn: '1h' });
res.json({ token });
} else {
res.status(401).send('잘못된 자격 증명입니다.');
}
});
3단계: Bearer Token으로 경로 보호하기
특정 경로를 보호하기 위해서는 들어오는 요청에서 Bearer Token을 검증하는 미들웨어가 필요합니다.
1. 인증 미들웨어 생성:
Bearer 토큰을 검증하는 미들웨어 함수를 생성합니다. 이 미들웨어는 들어오는 요청의 Authorization
헤더를 확인하고 비밀 키를 사용하여 토큰을 검증합니다.
const authenticateToken = (req, res, next) => {
const authHeader = req.headers['authorization'];
const token = authHeader && authHeader.split(' ')[1]; // Bearer <토큰>
if (token == null) return res.sendStatus(401); // 토큰이 없음
jwt.verify(token, SECRET_KEY, (err, user) => {
if (err) return res.sendStatus(403); // 잘못된 토큰
req.user = user;
next();
});
};
2. 경로 생성:
로그인 및 인증이 필요한 보호 경로에 대한 경로를 생성합니다.
const users = [
{ id: 1, username: 'user1', password: 'password1' },
{ id: 2, username: 'user2', password: 'password2' }
];
app.post('/login', (req, res) => {
const { username, password } = req.body;
const user = users.find(u => u.username === username && u.password === password);
if (!user) {
return res.status(400).send('사용자 이름 또는 비밀번호가 올바르지 않습니다.');
}
const token = jwt.sign({ username: user.username }, 'your_jwt_secret_key', { expiresIn: '1h' });
res.json({ token });
});
app.get('/protected', authenticateToken, (req, res) => {
res.send('이것은 보호된 경로입니다.');
});
4단계: 구현 테스트하기
서버를 실행합니다:
node app.js
구현을 테스트하려면:
- 로그인: 유효한
username
과password
를 포함하는 JSON 본문으로/login
에 POST 요청을 보냅니다. 자격 증명이 올바르면 JWT를 받게 됩니다. - 보호된 경로 접근:
/protected
에 대해Authorization
헤더를Bearer <your_token>
로 설정한 GET 요청을 보냅니다. 토큰이 유효하다면 보호된 경로에 접근할 수 있습니다.
Apidog을 사용하여 API Bearer Token 인증 테스트하기
Bearer token 인증은 웹 애플리케이션에서 API 요청을 보호하기 위해 일반적으로 사용되는 방법입니다. 다목적 API 도구인 Apidog은 이 과정을 단순화하여 개발자가 API 요청을 손쉽게 인증할 수 있게 해줍니다. 다음은 Apidog을 사용하여 API Bearer Token 인증을 테스트하는 단계별 안내입니다.
1단계: Apidog 설정하기
- Apidog 다운로드 및 설치: Apidog 다운로드 및 운영 체제에 대한 설치 지침을 따릅니다.
- 새 프로젝트 만들기: Apidog을 열고 API 요청 및 테스트를 관리할 수 있는 새 프로젝트를 생성합니다.
2단계: API 요청에 Bearer Token 추가하기
1. Bearer Token 인증 선택: 프로젝트 대시보드에서 새 API 요청을 생성합니다. "Auth"로 이동하고 드롭다운에서 "Bearer Token"을 선택합니다.
2. 토큰 입력: 토큰 값을 직접 입력합니다. Apidog은 실제 요청을 위해 자동으로 "Bearer"를 앞에 추가합니다.
3. 요청 보내기: Bearer 토큰이 설정되면 요청을 보냅니다. Apidog은 Authorization 헤더에 토큰을 포함시켜 보호된 리소스에 접근할 수 있게 합니다.
3단계: 응답 검증하기
요청을 보낸 후, API 호출이 성공했는지 응답을 확인하세요. 200 OK 상태는 일반적으로 성공적인 인증을 나타냅니다.

API 인증을 위한 Bearer Token 선택 이유
Bearer token 인증은 여러 가지 장점 덕분에 API 인증을 위해 널리 선택됩니다:
- 상태 비저장: Bearer 토큰을 사용하면 서버가 세션 상태를 유지하지 않고도 요청을 인증할 수 있어 애플리케이션 확장이 용이합니다.
- 단순성: 토큰은 구현 및 사용이 간편하며 일반적으로 HTTP Authorization 헤더에 포함됩니다.
- 보안: 토큰은 암호화될 수 있으며 만료 시간이 설정되어 보안을 강화합니다.
- 상호 운용성: Bearer 토큰은 표준화되어 있으며 다양한 플랫폼과 서비스 전반에서 사용할 수 있어 상호 운용성을 촉진합니다.
이러한 이점들은 Bearer 토큰을 API 보호를 위한 강력하고 유연한 옵션으로 만듭니다.
Bearer Token 보안을 위한 모범 사례
1. 강력한 비밀 키 사용:
JWT 서명을 위한 비밀 키가 복잡하고 안전하게 저장되어 있는지 확인하세요. 코드베이스에 하드코딩을 피하고 환경 변수를 사용하는 것을 고려하세요.
2. 토큰 만료:
토큰의 남용 위험을 최소화하기 위해 항상 만료 시간을 설정하세요. 정기적으로 토큰을 회전하고 무효화하세요.
3. HTTPS:
전송 중 데이터를 보호하기 위해 HTTPS를 사용하고, Bearer Token을 포함한 클라이언트와 서버 간의 암호화를 보장하세요.
4. 안전한 저장소:
클라이언트 측에서 토큰을 안전하게 저장하세요. HTTP 전용 및 보안 쿠키가 로컬 저장소 또는 세션 저장소보다 더 좋은 선택인 경우가 많습니다.
5. 속도 제한 및 모니터링:
무차별 대입 공격을 방지하기 위해 속도 제한을 구현하세요. 추가적으로, 무단 접근 시도를 모니터링하세요.
6. 침해된 토큰 블랙리스트:
접근을 즉시 철회할 필요가 있을 경우, 토큰 무효화를 위한 메커니즘, 예를 들어 블랙리스트를 유지하세요.
결론
Node.js와 Express 애플리케이션에서 JWT를 사용한 Bearer Token 인증은 API 보안을 위한 강력하고 확장 가능한 접근 방식을 제공합니다. 이 블로그에 설명된 단계들을 따르면 안전한 토큰 기반 인증을 구현하고 리소스를 효과적으로 보호할 수 있습니다.
보안은 지속적인 과정이며, Bearer Token이 여러 이점을 제공하는 반면, 최신 보안 모범 사례와 위협에 대한 정보를 항상 유지해야 합니다. 이 기초를 통해 Node.js를 사용하여 Express에서 안전하고 확장 가능하며 효율적인 API를 구축하는 길을 잘 걸어가고 있습니다.