웹 개발 실무 기술 A to Z
API 보안은 웹 개발에서 가장 중요한 요소 중 하나입니다.
API가 인증되지 않은 사용자에게 노출되면 데이터 유출, 해킹, DDoS 공격 등의 보안 위협에 취약해집니다.
이번 글에서는 **JWT(JSON Web Token)**와 OAuth 2.0을 활용한 API 인증 및 보안 방법을 상세히 다뤄보겠습니다.
1. API 인증이 필요한 이유
1-1. 보안 위협 종류
웹 API가 제대로 보호되지 않으면 다음과 같은 보안 문제에 노출될 수 있습니다.
보안 위협 설명
무단 접근 | 로그인 없이 민감한 데이터에 접근 가능 |
데이터 변조 | 공격자가 API 요청을 조작하여 데이터를 변경 |
세션 하이재킹 | 다른 사용자의 세션을 가로채서 로그인 상태를 유지 |
API 남용(DDoS 공격) | API를 과부하 상태로 만들어 정상적인 요청 불가능 |
1-2. API 인증이 해결하는 문제
✔️ 사용자 인증 (Authentication) → API 요청을 보낸 사용자가 누구인지 확인
✔️ 권한 부여 (Authorization) → 사용자가 특정 기능을 수행할 수 있는지 확인
✔️ 데이터 무결성 (Integrity) → 요청과 응답이 변조되지 않았음을 보장
2. API 인증 방식 비교
인증 방식 개념 예시
Session 기반 인증 | 서버가 세션을 저장하고 관리 | 쿠키 기반 로그인 (PHP, Django) |
Token 기반 인증 | 서버가 인증을 위한 토큰 발급 | JWT (JSON Web Token) |
OAuth 2.0 | 외부 서비스에서 인증을 처리 | Google, Facebook 로그인 |
API Key 기반 인증 | 고유한 API 키를 사용해 요청 인증 | OpenWeather API, Stripe API |
이번 글에서는 JWT와 OAuth 2.0을 중심으로 다뤄보겠습니다.
3. JWT(JSON Web Token) 인증
3-1. JWT란?
JWT(JSON Web Token)는 사용자 인증 및 정보 교환을 위한 토큰 기반 인증 방식입니다.
JWT는 클라이언트가 로그인하면 토큰을 발급받아 API 요청 시 사용하는 방식으로 동작합니다.
✔️ JWT 구조
JWT는 **헤더(Header), 페이로드(Payload), 서명(Signature)**의 세 부분으로 구성됩니다.
eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.
eyJ1c2VyX2lkIjoxLCJyb2xlIjoiYWRtaW4iLCJleHAiOjE2NjU0NTYwMDB9.
HMACSHA256(base64UrlEncode(header) + "." + base64UrlEncode(payload), secret)
- Header → 토큰 유형과 해싱 알고리즘 정보
- Payload → 사용자 ID, 권한, 만료 시간 (exp) 정보
- Signature → 변조 방지를 위한 서명
3-2. JWT 인증 흐름
1️⃣ 사용자가 로그인 요청 → 아이디 & 비밀번호 전송
2️⃣ 서버가 인증 후 JWT 발급
3️⃣ 클라이언트가 API 요청 시 JWT 포함 (Authorization: Bearer <token>)
4️⃣ 서버는 JWT를 검증하고 요청을 처리
3-3. Node.js + Express로 JWT 구현하기
(1) JWT 패키지 설치
npm install jsonwebtoken express bcryptjs dotenv
(2) 로그인 시 JWT 발급
const express = require("express");
const jwt = require("jsonwebtoken");
const bcrypt = require("bcryptjs");
require("dotenv").config();
const app = express();
app.use(express.json());
const users = [
{ id: 1, username: "admin", password: "$2a$10$abcdefghi" } // 암호화된 비밀번호 저장
];
// 로그인 API
app.post("/login", async (req, res) => {
const { username, password } = req.body;
const user = users.find(u => u.username === username);
if (!user || !(await bcrypt.compare(password, user.password))) {
return res.status(401).json({ error: "Invalid credentials" });
}
// JWT 발급
const token = jwt.sign({ userId: user.id }, process.env.JWT_SECRET, { expiresIn: "1h" });
res.json({ token });
});
(3) JWT 검증 미들웨어
const authMiddleware = (req, res, next) => {
const token = req.header("Authorization")?.split(" ")[1];
if (!token) return res.status(401).json({ error: "Access denied" });
try {
const decoded = jwt.verify(token, process.env.JWT_SECRET);
req.user = decoded;
next();
} catch (error) {
res.status(401).json({ error: "Invalid token" });
}
};
// 보호된 API 엔드포인트
app.get("/protected", authMiddleware, (req, res) => {
res.json({ message: "You have access!", user: req.user });
});
✅ 테스트 방법
- 로그인 → POST /login 요청 후 토큰을 받음
- JWT 포함하여 API 요청 → Authorization: Bearer <token> 헤더로 API 호출
4. OAuth 2.0 인증 (Google 로그인 예제)
4-1. OAuth 2.0이란?
OAuth 2.0은 소셜 로그인 및 타사 서비스 인증을 위한 표준 프로토콜입니다.
Google, Facebook, GitHub 로그인 시 사용됩니다.
4-2. OAuth 2.0 인증 흐름
1️⃣ 사용자가 Google 로그인 버튼 클릭
2️⃣ Google이 사용자에게 OAuth 인증 페이지 표시
3️⃣ 사용자가 로그인하면 Access Token 발급
4️⃣ 클라이언트가 Access Token을 API 요청에 포함
5️⃣ 서버는 Access Token을 검증하고 데이터 제공
4-3. Google OAuth 2.0 구현 (Node.js + Passport.js)
(1) OAuth 패키지 설치
npm install passport passport-google-oauth20 dotenv express-session
(2) Google OAuth 설정
Google Cloud에서 OAuth 2.0 클라이언트 ID 생성 후 .env 파일에 추가
GOOGLE_CLIENT_ID=your_google_client_id
GOOGLE_CLIENT_SECRET=your_google_client_secret
(3) Passport.js로 OAuth 2.0 인증
const passport = require("passport");
const GoogleStrategy = require("passport-google-oauth20").Strategy;
passport.use(new GoogleStrategy({
clientID: process.env.GOOGLE_CLIENT_ID,
clientSecret: process.env.GOOGLE_CLIENT_SECRET,
callbackURL: "/auth/google/callback"
}, (accessToken, refreshToken, profile, done) => {
return done(null, profile);
}));
app.get("/auth/google", passport.authenticate("google", { scope: ["profile", "email"] }));
app.get("/auth/google/callback", passport.authenticate("google", { failureRedirect: "/" }), (req, res) => {
res.json({ message: "Google Login Successful!", user: req.user });
});
✅ OAuth 2.0을 사용하면 로그인 정보를 저장하지 않고도 인증 가능
✅ Google, GitHub, Facebook 등 다양한 서비스 연동 가능
5. 마무리 및 다음 글 예고
이번 글에서는 JWT 인증과 OAuth 2.0 인증을 구현하는 방법을 다뤘습니다.
다음 글에서는 **웹 API 성능 최적화 방법 (캐싱, 레이트 리미팅, Gzip 압축)**을 소개하겠습니다.
다음 글 예고: "API 성능 최적화 – 캐싱, 압축, 레이트 리미팅 활용" 🚀
'project > 웹 개발 실무 기술 A to Z' 카테고리의 다른 글
웹 개발 실무 기술 A to Z #1 - A – API 설계 원칙: RESTful API와 GraphQL 비교 (0) | 2025.02.23 |
---|---|
웹 개발 실무 기술 A to Z #0 (0) | 2025.02.22 |