OAuth 2.0은 외부 애플리케이션에 안전하게 API 접근 권한을 위임할 때 사용하는 표준 프로토콜입니다. 이번 가이드에서는 Node.js와 OAuth2orize 모듈을 사용해 간단한 인증 서버(Authorization Server)를 만드는 과정을 보여드립니다.
⸻
📋 목차
1. OAuth 2.0 개요
2. 프로젝트 초기 설정
3. 데이터 모델 설계
4. OAuth2orize 서버 구성
5. 인증 코드(Authorization Code) 그랜트 구현
6. 토큰 발급(Token) 엔드포인트
7. 클라이언트 등록 예제
8. 테스트 및 검증
9. 실전 팁
⸻
1️⃣ OAuth 2.0 개요
• 역할 구분
• 리소스 소유자(Resource Owner): 사용자
• 클라이언트(Client): API 접근을 요청하는 애플리케이션
• 인증 서버(Authorization Server): 사용자 인증·토큰 발급
• 리소스 서버(Resource Server): 보호된 API 제공
• 주요 그랜트 타입
• Authorization Code, Implicit, Resource Owner Password, Client Credentials
이번 예제에선 웹 애플리케이션 인증에 가장 많이 쓰이는 Authorization Code 그랜트만 구현합니다.
⸻
2️⃣ 프로젝트 초기 설정
mkdir oauth2-server && cd oauth2-server
npm init -y
npm install express express-session body-parser oauth2orize passport passport-local
npm install --save-dev nodemon
// package.json scripts
"scripts": {
"dev": "nodemon index.js"
}
⸻
3️⃣ 데이터 모델 설계
간단화를 위해 메모리 스토어 사용 예시:
// models.js
const clients = [{
id: 'client1',
secret: 'secret1',
redirectUris: ['http://localhost:3000/callback']
}];
const codes = {}; // { code: { clientId, redirectUri, userId } }
const tokens = {}; // { accessToken: { clientId, userId } }
module.exports = { clients, codes, tokens };
실무에선 데이터베이스(MongoDB, PostgreSQL 등)로 대체하세요.
⸻
4️⃣ OAuth2orize 서버 구성
// index.js
const express = require('express');
const bodyParser = require('body-parser');
const session = require('express-session');
const oauth2orize = require('oauth2orize');
const passport = require('passport');
const LocalStrategy = require('passport-local').Strategy;
const {
clients, codes, tokens
} = require('./models');
const app = express();
const server = oauth2orize.createServer();
app.use(bodyParser.urlencoded({ extended: true }));
app.use(session({ secret: 'ssh!', resave: false, saveUninitialized: false }));
app.use(passport.initialize());
app.use(passport.session());
• oauth2orize.createServer()로 인증 서버 인스턴스 생성
• Express 세션·Passport로 사용자 인증 처리
⸻
5️⃣ 인증 코드 그랜트 구현
// Authorization Code 요청 처리
server.grant(oauth2orize.grant.code((client, redirectUri, user, ares, done) => {
const code = Math.random().toString(36).substring(7);
codes[code] = { clientId: client.id, redirectUri, userId: user.id };
done(null, code);
}));
• 사용자가 로그인 후 /authorize 엔드포인트 접근 시 승인 화면 표시
• 요청이 승인되면 임시 code 발급
⸻
6️⃣ 토큰 발급 엔드포인트
// 토큰 교환 처리
server.exchange(oauth2orize.exchange.code((client, code, redirectUri, done) => {
const authCode = codes[code];
if (!authCode || authCode.clientId !== client.id || authCode.redirectUri !== redirectUri) {
return done(null, false);
}
delete codes[code];
const token = Math.random().toString(36).substring(7);
tokens[token] = { clientId: client.id, userId: authCode.userId };
done(null, token);
}));
• /token에 클라이언트 인증(Basic Auth)과 함께 code, redirect_uri 제출
• 검증 후 access_token 발급
⸻
7️⃣ 클라이언트 등록 예제
// models.js (clients 배열에 추가)
clients.push({
id: 'webapp123',
secret: 'topsecret',
redirectUris: ['https://myapp.com/oauth/callback']
});
실제 운영 환경에선 관리 콘솔을 통해 Client ID·Secret, Redirect URI를 등록합니다.
⸻
8️⃣ 테스트 및 검증
1. 인가 코드 요청
GET /authorize?
response_type=code&
client_id=client1&
redirect_uri=http://localhost:3000/callback
2. 로그인 후 승인 → ?code=ABC123
3. 토큰 교환
curl -X POST http://localhost:4000/token \
-u client1:secret1 \
-d grant_type=authorization_code \
-d code=ABC123 \
-d redirect_uri=http://localhost:3000/callback
→ { "access_token":"XYZ456", "token_type":"Bearer" }
⸻
9️⃣ 실전 팁
• HTTPS 필수: Redirect URI·토큰 교환 구간 암호화
• Refresh Token: 토큰 만료 후 갱신 로직 추가
• 스코프(Scope): 권한 범위 제어
• CSRF 방지: state 파라미터 검증
• 로그 및 모니터링: 인증 이벤트 기록
⸻
이제 Node.js + OAuth2orize로 Authorization Code 그랜트 기반의 기본 OAuth 2.0 인증 서버가 완성되었습니다.
다음 주제에서는 gRPC 서버·클라이언트 구현: Go + Protocol Buffers를 살펴봅니다!
'IT & Tech 정보' 카테고리의 다른 글
🚀 Terraform으로 AWS 인프라 코드 관리 (0) | 2025.05.25 |
---|---|
🚀 gRPC 서버·클라이언트 구현: Go + Protocol Buffers (0) | 2025.05.25 |
🚀 Elasticsearch를 이용한 로그 수집·검색·대시보드: ELK 스택 (0) | 2025.05.25 |
🚀 WebSocket 기반 실시간 채팅 서버: Socket.IO + React (0) | 2025.05.25 |
🚀 GitHub Actions로 CI/CD 파이프라인 구성 (0) | 2025.05.25 |