OPEN HYPER STEP
← 목록으로 (stack-analysis)
STACK-ANALYSIS · 102 / 120
stack-analysis
CHAPTER 102 / 120
읽기 약 2
FUNCTION

인증 아키텍처: Session vs JWT vs OAuth2


핵심 개념

3가지 모델 비교·refresh token·SSO — 프로덕션 인증 결정.

본문

3가지 인증 모델

📋 코드 (16줄)
Session (서버 저장)
- 쿠키에 sessionId
- 서버 메모리/Redis에 매핑
- 로그아웃 즉시 무효화 가능
- 서버 부하 ↑

JWT (클라이언트 저장)
- 서명된 토큰 (stateless)
- 서버 부하 0
- 만료 시까지 무효화 어려움
- 토큰 도난 시 위험

OAuth2 (위임)
- Google/GitHub/Kakao 로그인
- 비밀번호 관리 안 함
- 외부 의존

결정 트리

📋 코드 (13줄)
서버가 1대?
├─ Yes
│   └─ Session (가장 단순)
└─ No (분산)
    ├─ Redis 사용 가능?
    │   ├─ Yes → Session + Redis
    │   └─ No → JWT
    │
    ├─ 마이크로서비스?
    │   └─ JWT (서비스 간 검증 쉬움)
    │
    └─ 외부 ID 공급자?
        └─ OAuth2 + JWT

Session 구현 (권장)

TYPESCRIPT📋 코드 (29줄)
import session from 'express-session';
import RedisStore from 'connect-redis';

app.use(session({
  store: new RedisStore({ client: redis, prefix: 'sess:' }),
  secret: process.env.SESSION_SECRET!,
  resave: false,
  saveUninitialized: false,
  cookie: {
    httpOnly: true,
    secure: true,           // HTTPS만
    sameSite: 'lax',        // CSRF 보호
    maxAge: 1000 * 60 * 60 * 24 * 7,
  },
}));


// 로그인
app.post('/login', async (req, res) => {
  const user = await authenticate(req.body);
  req.session.userId = user.id;
  res.json({ ok: true });
});


// 로그아웃 (서버에서 즉시 무효화 가능)
app.post('/logout', (req, res) => {
  req.session.destroy(() => res.json({ ok: true }));
});

JWT — Access + Refresh

TYPESCRIPT📋 코드 (51줄)
import jwt from 'jsonwebtoken';

const ACCESS_TTL = '15m';
const REFRESH_TTL = '7d';

async function login(email: string, password: string) {
  const user = await authenticate(email, password);

  const accessToken = jwt.sign(
    { sub: user.id, role: user.role, type: 'access' },
    process.env.JWT_ACCESS_SECRET!,
    { expiresIn: ACCESS_TTL },
  );

  const refreshToken = jwt.sign(
    { sub: user.id, type: 'refresh', jti: crypto.randomUUID() },
    process.env.JWT_REFRESH_SECRET!,
    { expiresIn: REFRESH_TTL },
  );

  // refresh는 DB 저장 (revoke 가능)
  await db.refreshToken.create({
    data: {
      userId: user.id,
      tokenHash: hash(refreshToken),
      expiresAt: new Date(Date.now() + 7 * 86400 * 1000),
    },
  });

  return { accessToken, refreshToken };
}


// 갱신
async function refresh(refreshToken: string) {
  const payload = jwt.verify(refreshToken, process.env.JWT_REFRESH_SECRET!) as any;

  // DB에서 유효성 확인 (revoke 가능)
  const stored = await db.refreshToken.findUnique({
    where: { tokenHash: hash(refreshToken) },
  });
  if (!stored || stored.revokedAt) throw new UnauthorizedError();

  // 회전 (rotation) — 옛 토큰 revoke + 새 토큰 발급
  await db.refreshToken.update({
    where: { id: stored.id },
    data: { revokedAt: new Date() },
  });

  return issueTokens(payload.sub);
}

토큰 저장 — 클라이언트

📋 코드 (11줄)
[보안 우선]
- accessToken: JS 메모리 (페이지 새로고침 시 refresh로 재발급)
- refreshToken: httpOnly Secure SameSite=Strict 쿠키


[구현 단순]
- 모두 localStorage (XSS 위험)


[모바일 앱]
- Secure Storage (Keychain·Keystore)

OAuth2 + JWT (조합)

TYPESCRIPT📋 코드 (28줄)
// Google OAuth → 우리 JWT 발급
app.get('/auth/google/callback', async (req, res) => {
  // 1. Google에서 access token 받음
  const googleToken = await exchangeCodeForToken(req.query.code);

  // 2. Google 사용자 정보 조회
  const profile = await fetchGoogleProfile(googleToken);

  // 3. 우리 DB에서 사용자 찾거나 생성
  let user = await db.user.findUnique({ where: { googleId: profile.id } });
  if (!user) {
    user = await db.user.create({
      data: {
        email: profile.email,
        name: profile.name,
        googleId: profile.id,
      },
    });
  }

  // 4. 우리 JWT 발급
  const tokens = await issueTokens(user.id);

  res.cookie('refreshToken', tokens.refreshToken, {
    httpOnly: true, secure: true, sameSite: 'lax',
  });
  res.redirect(`/?token=${tokens.accessToken}`);
});

SSO (Single Sign-On)

📋 코드 (13줄)
[OIDC (OpenID Connect)]
- OAuth2 위에 ID 레이어
- Google·Microsoft·Okta·Auth0


[SAML]
- 기업용 (legacy)
- Okta·OneLogin


[구현 — Clerk·Auth0·Workos]
- 자체 구현 대신 SaaS
- 시간 90% 절감

다음 챕터

CH.103 "OWASP Top 10 실전 방어 코드".


AI 프롬프트
🤖 AI에게 잘 물어보는 법 — 모델·전략별 프롬프트
Claude

무료: Sonnet 4.6 / Pro $20/mo: Opus 4.6

내 코드의 인증 아키텍처 부분을 분석해서
실전 분석 + 개선 우선순위를 알려줘.
ChatGPT

무료: GPT-5.5 / Plus $20/mo: GPT-5.5 Pro

인증 아키텍처 관련 베스트 프랙티스 5가지를
비교 분석해서 패턴 추출를 알려줘.
Gemini

무료: 2.5 Flash / Pro $19.99/mo: 3.1 Pro

내 프로젝트 전체에서 인증 아키텍처
최적화 가능 위치를 보고해줘.
Grok

무료: Grok 4.1 / SuperGrok $30/mo

2026년 한국 시장의 인증 아키텍처
트렌드를 솔직히 알려줘.

⭐ 이것만 기억하세요
인증 아키텍처: Session vs JWT vs OAuth2 이 3가지만 확실히 잡으세요
1.Session(Redis) = 단순·안전, JWT(stateless) = 분산·MSA
2.Refresh token rotation으로 도난 탐지
3.OAuth2 + 자체 JWT 조합 = 외부 ID + 내부 권한


공유하기
진행도 102 / 120