본문 바로가기

인증과 권한 관리 기초

신원 확인과 접근 허용을 구분하고 세션·토큰 인증, 역할·속성 기반 권한, 비밀번호 해시 원칙을 익힙니다.

이번 절에서는 인증(Authentication)과 권한 부여(Authorization)를 다룹니다.

대부분의 웹 애플리케이션은 로그인 기반 개인화와 역할별 기능 제한이 필요하며, 이 과정에서 인증/권한 관리는 웹 보안의 핵심이 됩니다.

이번 장에서는 인증과 권한 부여 개념을 구분하고, 세션 기반/토큰 기반 인증 방식과 권한 관리 기본 원칙을 정리합니다.

인증·인가 요청 게이트 — 상태 추적

본문 보호 API에서 자격 증명 검증 실패 401, 역할 거부 403, 허용 handler의 도달 여부가 달라진다. 로그인과 작업 인가를 별도 현재 상태로 보여 줄 수 있다.

로그인 성공 뒤에도 작업 권한을 확인합니다

AUTHENTICATION & AUTHORIZATION

로그인 성공 뒤에도 작업 권한을 확인합니다

인증은 신원·자격 증명을 확인하고, 인가는 요청한 자원과 행동의 허용 여부를 결정합니다. 보호 API의 두 검사를 분리합니다.

인증 뒤에도 요청한 역할과 작업을 검사한다원Express예제6노드5분기다. 없는토큰/검증오류는401challenge. 유효한자격증명만역할인가에들어가고거부403/허용handler다. admin-dashboard는admin만,게시물생성은admin또는user가허용된다. 원간략코드의Bearer스킴파싱·검증옵션·대상소유권검사는생략이며그림의유효노드가이를새구현한것은아니다. mobile동일하다.보호 API 요청원 middleware 예제자격 증명유효한가?401인증 challenge이 역할의작업을 허용?403인가 거부핸들러 실행기타 검증은 별도실패유효거부허용
인증 뒤에도 요청한 역할과 작업을 검사한다원Express예제6노드5분기다. 없는토큰/검증오류는401challenge. 유효한자격증명만역할인가에들어가고거부403/허용handler다. admin-dashboard는admin만,게시물생성은admin또는user가허용된다. 원간략코드의Bearer스킴파싱·검증옵션·대상소유권검사는생략이며그림의유효노드가이를새구현한것은아니다. mobile동일하다.보호 API 요청원 예제 범위자격 증명유효한가?401인증 challenge이 역할의작업을 허용?403인가 거부핸들러 실행기타 검증성공 여부는 별도실패유효거부허용
인증과 인가의 요청 분기보호 API 요청의 인증 실패는 401, 인증 후 인가 거부는 403, 모두 통과한 요청은 업무 처리로 이어집니다.보호 API 요청인증이 필요한 자원 예인증 · 자격 증명 유효?세션 · 토큰 검증401 · 유효한 인증 필요실패 응답 · 작업 중단없음·실패유효인가 · 이 작업 허용?역할 · 대상 · 소유 관계403 · 작업 거부유효한 인증 · 권한 부족거부허용업무 처리다른 검증·오류 처리도 필요
  1. 인증 · 자격 증명 확인

    세션·토큰이 없거나 유효하지 않으면 401로 중단합니다. 유효하면 인가로 진행합니다.

  2. 인가 · 대상과 작업 확인

    역할뿐 아니라 필요한 대상·소유 관계를 확인합니다. 권한이 없으면 403, 허용하면 업무 처리로 진행합니다.

  3. 업무 처리

    통과 뒤에도 입력·업무 검증에 실패할 수 있으므로 성공 응답이 항상 보장되지는 않습니다.

교재의 Express 미들웨어

authenticateToken → authorizeRoles → handler 순서입니다. admin-dashboard는 admin 역할, 게시물 생성은 admin 또는 user 역할을 허용합니다.

공개 자원과 응답 정책

공개 자원은 로그인 없이도 정책상 허용할 수 있습니다. 민감한 대상의 존재를 숨기려고 404를 선택하는 정책은 별도로 설계합니다.

401은 유효한 인증 자격 증명이 필요하다는 뜻이며 적절한 WWW-Authenticate 헤더를 포함합니다. 403은 서버가 요청 처리를 거부한다는 뜻으로, 모든 경우를 단순히 “신원을 알고 있음”으로 정의하지 않습니다.

이 예의 조건

  • 원도표의 전체 구조와 설명은 위 관계도와 표에서 유지합니다. 아래 인쇄 표에도 원도표의 관계·조건·라벨·설명·주석을 보존합니다.
  • 두 관찰 칸의 위치는 고정입니다. 관찰 상태는 해당 순간의 값이며, 동작·이유는 그 조건에서의 판정과 변화 원인입니다. 독립 비교와 실패 분기는 별도 조건으로 읽고 모든 분기를 한 요청의 필수 실행 순서로 이어 읽지 않습니다.
  • 세 장면은 서로 독립적인 보호 API 요청 A·B·C의 비교입니다. 401 응답 뒤 같은 요청이 403이나 허용으로 진행하지 않습니다. 이 예제의 403은 인증을 통과했지만 요구 역할이 부족한 경우입니다.
관계도의 보충 설명
원도표의 전체 관계·조건·설명
구분내용
전체 관계·조건 설명원 Express 예제의 노드 6개·분기 5개다. 없는 토큰/검증 오류는 401 challenge로 응답한다. 유효한 자격 증명만 역할 인가에 들어가고 거부 403/허용 handler로 갈린다. admin-dashboard는 admin만, 게시물 생성은 admin 또는 user가 허용된다. 원 간략 코드의 Bearer 스킴 파싱·검증 옵션·대상 소유권 검사는 생략이며 그림의 유효 노드가 이를 새로 구현한 것은 아니다. mobile도 동일하다.
원도표 조건·주석인증 · 자격 증명 확인: 세션·토큰이 없거나 유효하지 않으면 401로 중단합니다. 유효하면 인가로 진행합니다.
원도표 조건·주석인가 · 대상과 작업 확인: 역할뿐 아니라 필요한 대상·소유 관계를 확인합니다. 권한이 없으면 403, 허용하면 업무 처리로 진행합니다.
원도표 조건·주석업무 처리: 통과 뒤에도 입력·업무 검증에 실패할 수 있으므로 성공 응답이 항상 보장되지는 않습니다.
전체 상태와 변화 근거
장면현재 관찰값설명변화 이유
요청 A · 인증 없음HTTP: 401 / handler: 실행 안 함보호 경로에서 유효한 신원을 얻지 못했다신원을 확인하지 못해 요청을 중단한다
요청 B · 역할 부족HTTP: 403 / handler: 실행 안 함신원은 있으나 요구 권한이 없다요청 B는 인증을 통과해도 요구 역할이 없어 인가 단계에서 중단한다
요청 C · 허용HTTP: 업무 handler 결과 / handler: 실행신원과 역할 조건을 모두 통과한다권한 확인 뒤에만 보호 동작을 수행한다

인증·인가 요청 게이트 — 상태 추적

본문 보호 API에서 자격 증명 검증 실패 401, 역할 거부 403, 허용 handler의 도달 여부가 달라진다. 로그인과 작업 인가를 별도 현재 상태로 보여 줄 수 있다.

로그인 성공 뒤에도 작업 권한을 확인합니다

AUTHENTICATION & AUTHORIZATION

로그인 성공 뒤에도 작업 권한을 확인합니다

인증은 신원·자격 증명을 확인하고, 인가는 요청한 자원과 행동의 허용 여부를 결정합니다. 보호 API의 두 검사를 분리합니다.

인증 뒤에도 요청한 역할과 작업을 검사한다원Express예제6노드5분기다. 없는토큰/검증오류는401challenge. 유효한자격증명만역할인가에들어가고거부403/허용handler다. admin-dashboard는admin만,게시물생성은admin또는user가허용된다. 원간략코드의Bearer스킴파싱·검증옵션·대상소유권검사는생략이며그림의유효노드가이를새구현한것은아니다. mobile동일하다.보호 API 요청원 middleware 예제자격 증명유효한가?401인증 challenge이 역할의작업을 허용?403인가 거부핸들러 실행기타 검증은 별도실패유효거부허용
인증 뒤에도 요청한 역할과 작업을 검사한다원Express예제6노드5분기다. 없는토큰/검증오류는401challenge. 유효한자격증명만역할인가에들어가고거부403/허용handler다. admin-dashboard는admin만,게시물생성은admin또는user가허용된다. 원간략코드의Bearer스킴파싱·검증옵션·대상소유권검사는생략이며그림의유효노드가이를새구현한것은아니다. mobile동일하다.보호 API 요청원 예제 범위자격 증명유효한가?401인증 challenge이 역할의작업을 허용?403인가 거부핸들러 실행기타 검증성공 여부는 별도실패유효거부허용
인증과 인가의 요청 분기보호 API 요청의 인증 실패는 401, 인증 후 인가 거부는 403, 모두 통과한 요청은 업무 처리로 이어집니다.보호 API 요청인증이 필요한 자원 예인증 · 자격 증명 유효?세션 · 토큰 검증401 · 유효한 인증 필요실패 응답 · 작업 중단없음·실패유효인가 · 이 작업 허용?역할 · 대상 · 소유 관계403 · 작업 거부유효한 인증 · 권한 부족거부허용업무 처리다른 검증·오류 처리도 필요
  1. 인증 · 자격 증명 확인

    세션·토큰이 없거나 유효하지 않으면 401로 중단합니다. 유효하면 인가로 진행합니다.

  2. 인가 · 대상과 작업 확인

    역할뿐 아니라 필요한 대상·소유 관계를 확인합니다. 권한이 없으면 403, 허용하면 업무 처리로 진행합니다.

  3. 업무 처리

    통과 뒤에도 입력·업무 검증에 실패할 수 있으므로 성공 응답이 항상 보장되지는 않습니다.

교재의 Express 미들웨어

authenticateToken → authorizeRoles → handler 순서입니다. admin-dashboard는 admin 역할, 게시물 생성은 admin 또는 user 역할을 허용합니다.

공개 자원과 응답 정책

공개 자원은 로그인 없이도 정책상 허용할 수 있습니다. 민감한 대상의 존재를 숨기려고 404를 선택하는 정책은 별도로 설계합니다.

401은 유효한 인증 자격 증명이 필요하다는 뜻이며 적절한 WWW-Authenticate 헤더를 포함합니다. 403은 서버가 요청 처리를 거부한다는 뜻으로, 모든 경우를 단순히 “신원을 알고 있음”으로 정의하지 않습니다.

이 예의 조건

  • 원도표의 전체 구조와 설명은 위 관계도와 표에서 유지합니다. 아래 인쇄 표에도 원도표의 관계·조건·라벨·설명·주석을 보존합니다.
  • 두 관찰 칸의 위치는 고정입니다. 관찰 상태는 해당 순간의 값이며, 동작·이유는 그 조건에서의 판정과 변화 원인입니다. 독립 비교와 실패 분기는 별도 조건으로 읽고 모든 분기를 한 요청의 필수 실행 순서로 이어 읽지 않습니다.
  • 세 장면은 서로 독립적인 보호 API 요청 A·B·C의 비교입니다. 401 응답 뒤 같은 요청이 403이나 허용으로 진행하지 않습니다. 이 예제의 403은 인증을 통과했지만 요구 역할이 부족한 경우입니다.

관계도의 보충 설명

원도표의 전체 관계·조건·설명
구분내용
전체 관계·조건 설명원 Express 예제의 노드 6개·분기 5개다. 없는 토큰/검증 오류는 401 challenge로 응답한다. 유효한 자격 증명만 역할 인가에 들어가고 거부 403/허용 handler로 갈린다. admin-dashboard는 admin만, 게시물 생성은 admin 또는 user가 허용된다. 원 간략 코드의 Bearer 스킴 파싱·검증 옵션·대상 소유권 검사는 생략이며 그림의 유효 노드가 이를 새로 구현한 것은 아니다. mobile도 동일하다.
원도표 조건·주석인증 · 자격 증명 확인: 세션·토큰이 없거나 유효하지 않으면 401로 중단합니다. 유효하면 인가로 진행합니다.
원도표 조건·주석인가 · 대상과 작업 확인: 역할뿐 아니라 필요한 대상·소유 관계를 확인합니다. 권한이 없으면 403, 허용하면 업무 처리로 진행합니다.
원도표 조건·주석업무 처리: 통과 뒤에도 입력·업무 검증에 실패할 수 있으므로 성공 응답이 항상 보장되지는 않습니다.
전체 상태와 변화 근거
장면현재 관찰값설명변화 이유
요청 A · 인증 없음HTTP: 401 / handler: 실행 안 함보호 경로에서 유효한 신원을 얻지 못했다신원을 확인하지 못해 요청을 중단한다
요청 B · 역할 부족HTTP: 403 / handler: 실행 안 함신원은 있으나 요구 권한이 없다요청 B는 인증을 통과해도 요구 역할이 없어 인가 단계에서 중단한다
요청 C · 허용HTTP: 업무 handler 결과 / handler: 실행신원과 역할 조건을 모두 통과한다권한 확인 뒤에만 보호 동작을 수행한다

인증 vs 권한 부여

이 두 용어는 자주 혼용되지만, 웹 보안에서는 명확히 다른 의미를 가집니다.

  • 인증 (Authentication)
    • 누구인지 확인하는 과정입니다. 사용자에게 너는 누구냐?라고 물었을 때, 사용자가 본인임을 증명하는 과정입니다.
    • 사용자가 주장하는 신원(ID)이 실제와 일치하는지 확인하는 프로세스입니다.
    • 예시: 사용자 ID와 비밀번호를 입력하여 로그인하는 것, 지문 인식, OTP(일회용 비밀번호) 입력 등.
  • 권한 부여 (Authorization)
    • 무엇을 할 수 있는지 결정하는 과정입니다. 너는 무엇을 할 수 있느냐?라는 질문에 대해, 사용자에게 허용된 작업이 무엇인지 확인하는 과정입니다.
    • 인증된 사용자에게 특정 자원(데이터, 기능)에 대한 접근 권한을 부여하거나 거부하는 프로세스입니다.
    • 예시: 로그인한 사용자가 자신의 프로필을 수정할 수 있는지, 관리자만 특정 게시물을 삭제할 수 있는지, 유료 구독자만 프리미엄 콘텐츠를 볼 수 있는지 등.

요약: 인증은 신원 확인이고, 권한 부여는 허가된 작업의 범위 결정입니다.

이 절의 보호 API는 인증으로 신원을 확인한 뒤 권한을 검사합니다.

공개 자원처럼 익명 사용자에게 허용된 접근도 있으므로, 모든 인가 정책에 로그인이 필요한 것은 아닙니다.


사용자 인증 구현 방식

웹 애플리케이션에서 사용자를 인증하는 대표적인 두 가지 방식이 있습니다.

세션 기반 인증

세션 기반 인증 (Session-based Authentication)은 전통적인 웹 애플리케이션에서 널리 사용되던 방식입니다.

  • 동작 방식

    사용자가 ID와 비밀번호로 로그인 요청을 보냅니다.

    서버는 사용자의 신원을 확인한 후, 고유한 세션 ID(Session ID)를 생성합니다.

    이 세션 ID는 서버의 메모리나 데이터베이스에 저장되고, 사용자에게는 이 세션 ID를 포함하는 쿠키(Cookie)를 응답으로 보냅니다.

    클라이언트(브라우저)는 이 쿠키를 저장하고, 도메인·경로·Secure·SameSite와 요청의 credentials 조건을 충족하는 요청에 쿠키를 보냅니다.

    서버는 요청에 포함된 세션 ID를 확인하여, 서버에 저장된 세션 정보와 일치하는지 검증합니다.

    일치하면 해당 사용자가 로그인된 것으로 간주하고 요청을 처리합니다.

    로그아웃 시 서버에서 세션 정보를 삭제합니다.

  • 장점
    • 보안성: 사용자 정보는 서버에 보관하지만, 유효한 세션 ID는 로그인 권한에 연결되는 비밀입니다. ID가 탈취되면 세션을 악용할 수 있으므로 보호와 만료·폐기 관리가 필요합니다.
    • 세션 관리의 용이성 (서버에서 세션 만료, 강제 로그아웃 등 제어).
  • 단점
    • 확장성 (Scalability): 서버에서 세션 상태를 유지해야 하므로, 여러 대의 서버(로드 밸런싱)를 사용하는 경우 모든 서버가 세션 정보를 공유해야 하는 복잡성이 발생합니다 (Sticky Session 또는 Redis와 같은 외부 세션 저장소 필요).
    • CORS (Cross-Origin Resource Sharing) 문제: 다른 도메인 간의 요청 시 쿠키가 전송되지 않거나 보안 제약이 있어 복잡해질 수 있습니다.
    • 모바일 앱 대응 어려움: 모바일 앱에서는 웹 쿠키를 직접 관리하기 어렵습니다.

토큰 기반 인증

토큰 기반 인증 (Token-based Authentication)은 SPA, 모바일 앱, 마이크로서비스 등에서 사용하는 선택지입니다. 앱의 종류만으로 사용 비율이나 적합성을 단정하지 않고 수명·폐기·검증 정책을 비교합니다.

특히 JWT (JSON Web Token)가 대표적입니다.

  • 동작 방식

    사용자가 ID와 비밀번호로 로그인 요청을 보냅니다.

    서버는 사용자의 신원을 확인한 후, 사용자 정보(payload)를 담고 서버의 비밀 키로 서명(signature)한 토큰(Token)을 생성합니다.

    (예: JWT)

    이 토큰을 클라이언트에게 응답으로 보냅니다.

    자체 포함 토큰은 매번 세션 레코드를 조회하지 않고 검증할 수 있습니다. refresh 회전이나 폐기 목록에는 서버 상태가 필요할 수 있습니다.

    클라이언트(브라우저/앱)는 이 토큰을 로컬 스토리지, 세션 스토리지 또는 쿠키(보안을 위해 HttpOnly 쿠키 권장)에 저장합니다.

    헤더 방식은 JavaScript가 읽을 수 있는 토큰을 필요한 요청의 Authorization에 넣습니다. HttpOnly 쿠키 방식은 JavaScript로 읽지 않고 브라우저가 쿠키로 전송하므로 별도의 CSRF·쿠키 정책이 필요합니다.

    (예: Authorization: Bearer <token>)

    서버는 요청에 포함된 토큰의 유효성(서명 검증, 만료 시간 확인 등)을 검증합니다.

    토큰이 유효하면 해당 사용자의 권한을 확인하고 요청을 처리합니다.

  • JWT (JSON Web Token): 토큰 기반 인증의 표준 중 하나.

    • 이 절에서 비교하는 서명된 JWS 방식은 세 부분으로 구성: Header.Payload.Signature. 암호화한 JWE 표현까지 모두 세 부분이라고 일반화하지 않습니다.
    • Header: 토큰 타입(JWT), 서명 알고리즘(HMAC SHA256 등)
    • Payload: 사용자 ID, 만료 시간 등 실제 정보(클레임)
    • Signature: JWS 방식 JWT는 인코딩한 Header와 Payload에 MAC 또는 디지털 서명을 적용해 무결성을 검증합니다. 서명만으로 Payload가 암호화되지는 않습니다.
  • 장점
    • 확장성 (Scalability): 자체 포함 토큰은 매번 세션 레코드를 조회하지 않고 검증할 수 있어 여러 서버에서 사용할 수 있습니다. 검증 키·수명·정책을 공유해야 하며 refresh·폐기에는 서버 상태가 필요할 수 있습니다.
    • 교차 출처 요청: Authorization 헤더를 사용해도 브라우저의 CORS 검사를 받습니다. 서버의 Origin·헤더 허용과 preflight 처리가 필요합니다.
    • 모바일 앱 친화적: 모바일 앱에서도 쉽게 토큰을 저장하고 전송할 수 있습니다.
    • 분리된 프론트엔드/백엔드: 프론트엔드와 백엔드가 완전히 분리되어 개발될 때 이상적입니다.
  • 단점
    • 토큰 탈취 위험: 토큰이 클라이언트 측에 저장되므로 XSS 공격 등으로 토큰이 탈취될 경우 보안에 취약해질 수 있습니다. (Local Storage보다는 HttpOnly 쿠키에 저장하는 것이 더 안전함)
    • 토큰 무효화 어려움: 서명만 독립적으로 검증하는 토큰은 별도 폐기 검사 없이 발급 때의 수명까지 받아들일 수 있으므로, 즉시 무효화가 필요하면 추가 정책을 설계합니다 (블랙리스트 관리 또는 짧은 만료 시간 + Refresh Token 사용).
    • 페이로드 크기: 페이로드에 많은 정보를 담으면 토큰의 크기가 커져 네트워크 트래픽에 영향을 줄 수 있습니다.

세션 vs. 토큰 요약

세션과 토큰 생명주기 선택 — 상태 추적

세션과 JWT의 발급·전송·검증·로그아웃 뒤 서버/클라이언트 상태가 다르다. 클라이언트 JWT 제거가 복사본 즉시 폐기가 아님을 같은 역할의 상태 변화로 드러낼 가치가 있다.

세션과 JWT는 검증·폐기 책임이 다릅니다

SESSION & SIGNED TOKEN

세션과 JWT는 검증·폐기 책임이 다릅니다

같은 로그인 이후에도 서버 상태를 조회하는 방식과 서명된 클레임을 검증하는 방식의 수명 관리가 다릅니다. 앱 종류만으로 한 방식을 고르지 않습니다.

전송·검증·폐기 책임을 두 수명으로 비교한다8노드6진행관계의두독립수명이다. 세션서버상태조회와JWT서명검증을구별하되JWT에도refresh/폐기상태가필요할수있다. 쿠키와토큰은반대개념이아니다. 마지막JWT클라이언트제거는복사본의즉시폐기가아니며별도서버정책이필요하다. 서명은payload암호화가아니고mobile같다.서버 세션서명된 JWT서버 세션 발급ID ↔ 사용자 상태ID 쿠키 전송Secure·HttpOnlySameSite 정책서버 상태 조회만료·폐기 확인세션 로그아웃서버 레코드 폐기클라이언트 정리서명된 JWT 발급클레임·만료토큰 전송헤더 또는 쿠키각 위협 검토검증 후 인가서명·수명·대상요청 권한 검사JWT 로그아웃클라이언트 제거즉시 폐기는 별도
전송·검증·폐기 책임을 두 수명으로 비교한다8노드6진행관계의두독립수명이다. 세션서버상태조회와JWT서명검증을구별하되JWT에도refresh/폐기상태가필요할수있다. 쿠키와토큰은반대개념이아니다. 마지막JWT클라이언트제거는복사본의즉시폐기가아니며별도서버정책이필요하다. 서명은payload암호화가아니고mobile같다.서버 세션서명된 JWT서버 세션 발급ID ↔ 사용자 상태ID 쿠키 전송Secure·HttpOnlySameSite 정책서버 상태 조회만료·폐기 확인세션 로그아웃서버 레코드 폐기클라이언트 정리서명된 JWT 발급클레임·만료토큰 전송헤더 또는 쿠키각 위협 검토검증 후 인가서명·수명·대상요청 권한 검사JWT 로그아웃클라이언트 제거즉시 폐기는 별도

1 · 서버 세션 발급

로그인 검증 뒤 예측하기 어려운 세션 ID를 만들고 서버의 사용자 상태와 연결합니다.

1 · 서명된 JWT 발급

로그인 검증 뒤 필요한 클레임과 만료를 담아 서명합니다. refresh token은 필요한 설계에서 별도로 발급합니다.

2 · 세션 ID 보관·전송

보통 Secure·HttpOnly·SameSite 쿠키로 전달합니다. HTTPS와 쿠키 범위·credentials 조건을 적용합니다.

2 · JWT 보관·전송

Authorization 헤더 또는 쿠키를 선택합니다. HttpOnly 쿠키는 JS로 읽어 헤더에 넣을 수 없고 브라우저가 쿠키로 전송합니다.

3 · 세션 요청 검증

세션 레코드와 만료·폐기 상태를 조회합니다. 로그인·권한 변경 시 ID를 재발급해 세션 고정을 방지합니다.

3 · JWT 요청 검증

허용 알고리즘·서명·만료·발급자·대상을 검증한 뒤 요청 권한을 검사합니다. refresh를 쓰면 회전·재사용 탐지 정책도 설계합니다.

4 · 세션 로그아웃

서버 레코드를 무효화하고 클라이언트 쿠키도 정리합니다. 유휴·최대 수명 정책을 적용합니다.

4 · JWT 로그아웃

클라이언트 제거만으로 이미 발급된 JWT가 즉시 무효화되지 않습니다. 짧은 만료·폐기 목록·refresh 폐기를 함께 검토합니다.

전송 방식과 위협

쿠키 전송은 CSRF 정책을, JS가 읽을 수 있는 저장소와 헤더 방식은 XSS·토큰 탈취 위험을 검토합니다. HttpOnly도 XSS가 사용자 대신 요청하는 것을 막지는 않습니다.

분산 운영과 서버 상태

세션도 공유 저장소로 여러 서버가 사용할 수 있습니다. JWT도 refresh 회전·즉시 폐기·정책 변경을 관리하면 서버 상태가 필요할 수 있습니다.

여기서는 서명된 JWT를 비교합니다. 서명은 무결성 검증이며 payload 암호화가 아닙니다. 쿠키와 토큰은 서로 반대 개념이 아니며, 토큰을 쿠키로 전달할 수도 있습니다.

이 예의 조건

  • 원도표의 전체 구조와 설명은 위 관계도와 표에서 유지합니다. 아래 인쇄 표에도 원도표의 관계·조건·라벨·설명·주석을 보존합니다.
  • 두 관찰 칸의 위치는 고정입니다. 관찰 상태는 해당 순간의 값이며, 동작·이유는 그 조건에서의 판정과 변화 원인입니다. 독립 비교와 실패 분기는 별도 조건으로 읽고 모든 분기를 한 요청의 필수 실행 순서로 이어 읽지 않습니다.
관계도의 보충 설명
원도표의 전체 관계·조건·설명
구분내용
전체 관계·조건 설명노드 8개·진행 관계 6개의 두 독립 수명이다. 세션 서버 상태 조회와 JWT 서명 검증을 구별하되 JWT에도 refresh/폐기 상태가 필요할 수 있다. 쿠키와 토큰은 반대 개념이 아니다. 마지막 JWT 클라이언트 제거는 복사본의 즉시 폐기가 아니며 별도 서버 정책이 필요하다. 서명은 payload 암호화가 아니고 mobile도 같다.
전체 상태와 변화 근거
장면현재 관찰값설명변화 이유
로그인 뒤세션: 서버 상태 참조 / JWT: 서명된 credential세션 식별자 또는 서명 토큰이 클라이언트에 있다두 모델의 검증 원천이 다르다
로그아웃 처리세션: 서버 기록 무효 / JWT: 로컬 제거세션은 서버에서 무효화하고 JWT는 로컬 보관본을 지울 수 있다로컬 제거가 복사된 토큰의 폐기를 뜻하지 않는다
다시 제시한 credential세션: 거절 / JWT: 만료/폐기 정책에 따름세션은 무효 기록에 의해 거절되고 JWT는 추가 폐기 정책이 필요하다같은 logout 표시에서도 서버 검증 결과가 다를 수 있다

세션과 토큰 생명주기 선택 — 상태 추적

세션과 JWT의 발급·전송·검증·로그아웃 뒤 서버/클라이언트 상태가 다르다. 클라이언트 JWT 제거가 복사본 즉시 폐기가 아님을 같은 역할의 상태 변화로 드러낼 가치가 있다.

세션과 JWT는 검증·폐기 책임이 다릅니다

SESSION & SIGNED TOKEN

세션과 JWT는 검증·폐기 책임이 다릅니다

같은 로그인 이후에도 서버 상태를 조회하는 방식과 서명된 클레임을 검증하는 방식의 수명 관리가 다릅니다. 앱 종류만으로 한 방식을 고르지 않습니다.

전송·검증·폐기 책임을 두 수명으로 비교한다8노드6진행관계의두독립수명이다. 세션서버상태조회와JWT서명검증을구별하되JWT에도refresh/폐기상태가필요할수있다. 쿠키와토큰은반대개념이아니다. 마지막JWT클라이언트제거는복사본의즉시폐기가아니며별도서버정책이필요하다. 서명은payload암호화가아니고mobile같다.서버 세션서명된 JWT서버 세션 발급ID ↔ 사용자 상태ID 쿠키 전송Secure·HttpOnlySameSite 정책서버 상태 조회만료·폐기 확인세션 로그아웃서버 레코드 폐기클라이언트 정리서명된 JWT 발급클레임·만료토큰 전송헤더 또는 쿠키각 위협 검토검증 후 인가서명·수명·대상요청 권한 검사JWT 로그아웃클라이언트 제거즉시 폐기는 별도
전송·검증·폐기 책임을 두 수명으로 비교한다8노드6진행관계의두독립수명이다. 세션서버상태조회와JWT서명검증을구별하되JWT에도refresh/폐기상태가필요할수있다. 쿠키와토큰은반대개념이아니다. 마지막JWT클라이언트제거는복사본의즉시폐기가아니며별도서버정책이필요하다. 서명은payload암호화가아니고mobile같다.서버 세션서명된 JWT서버 세션 발급ID ↔ 사용자 상태ID 쿠키 전송Secure·HttpOnlySameSite 정책서버 상태 조회만료·폐기 확인세션 로그아웃서버 레코드 폐기클라이언트 정리서명된 JWT 발급클레임·만료토큰 전송헤더 또는 쿠키각 위협 검토검증 후 인가서명·수명·대상요청 권한 검사JWT 로그아웃클라이언트 제거즉시 폐기는 별도

1 · 서버 세션 발급

로그인 검증 뒤 예측하기 어려운 세션 ID를 만들고 서버의 사용자 상태와 연결합니다.

1 · 서명된 JWT 발급

로그인 검증 뒤 필요한 클레임과 만료를 담아 서명합니다. refresh token은 필요한 설계에서 별도로 발급합니다.

2 · 세션 ID 보관·전송

보통 Secure·HttpOnly·SameSite 쿠키로 전달합니다. HTTPS와 쿠키 범위·credentials 조건을 적용합니다.

2 · JWT 보관·전송

Authorization 헤더 또는 쿠키를 선택합니다. HttpOnly 쿠키는 JS로 읽어 헤더에 넣을 수 없고 브라우저가 쿠키로 전송합니다.

3 · 세션 요청 검증

세션 레코드와 만료·폐기 상태를 조회합니다. 로그인·권한 변경 시 ID를 재발급해 세션 고정을 방지합니다.

3 · JWT 요청 검증

허용 알고리즘·서명·만료·발급자·대상을 검증한 뒤 요청 권한을 검사합니다. refresh를 쓰면 회전·재사용 탐지 정책도 설계합니다.

4 · 세션 로그아웃

서버 레코드를 무효화하고 클라이언트 쿠키도 정리합니다. 유휴·최대 수명 정책을 적용합니다.

4 · JWT 로그아웃

클라이언트 제거만으로 이미 발급된 JWT가 즉시 무효화되지 않습니다. 짧은 만료·폐기 목록·refresh 폐기를 함께 검토합니다.

전송 방식과 위협

쿠키 전송은 CSRF 정책을, JS가 읽을 수 있는 저장소와 헤더 방식은 XSS·토큰 탈취 위험을 검토합니다. HttpOnly도 XSS가 사용자 대신 요청하는 것을 막지는 않습니다.

분산 운영과 서버 상태

세션도 공유 저장소로 여러 서버가 사용할 수 있습니다. JWT도 refresh 회전·즉시 폐기·정책 변경을 관리하면 서버 상태가 필요할 수 있습니다.

여기서는 서명된 JWT를 비교합니다. 서명은 무결성 검증이며 payload 암호화가 아닙니다. 쿠키와 토큰은 서로 반대 개념이 아니며, 토큰을 쿠키로 전달할 수도 있습니다.

이 예의 조건

  • 원도표의 전체 구조와 설명은 위 관계도와 표에서 유지합니다. 아래 인쇄 표에도 원도표의 관계·조건·라벨·설명·주석을 보존합니다.
  • 두 관찰 칸의 위치는 고정입니다. 관찰 상태는 해당 순간의 값이며, 동작·이유는 그 조건에서의 판정과 변화 원인입니다. 독립 비교와 실패 분기는 별도 조건으로 읽고 모든 분기를 한 요청의 필수 실행 순서로 이어 읽지 않습니다.

관계도의 보충 설명

원도표의 전체 관계·조건·설명
구분내용
전체 관계·조건 설명노드 8개·진행 관계 6개의 두 독립 수명이다. 세션 서버 상태 조회와 JWT 서명 검증을 구별하되 JWT에도 refresh/폐기 상태가 필요할 수 있다. 쿠키와 토큰은 반대 개념이 아니다. 마지막 JWT 클라이언트 제거는 복사본의 즉시 폐기가 아니며 별도 서버 정책이 필요하다. 서명은 payload 암호화가 아니고 mobile도 같다.
전체 상태와 변화 근거
장면현재 관찰값설명변화 이유
로그인 뒤세션: 서버 상태 참조 / JWT: 서명된 credential세션 식별자 또는 서명 토큰이 클라이언트에 있다두 모델의 검증 원천이 다르다
로그아웃 처리세션: 서버 기록 무효 / JWT: 로컬 제거세션은 서버에서 무효화하고 JWT는 로컬 보관본을 지울 수 있다로컬 제거가 복사된 토큰의 폐기를 뜻하지 않는다
다시 제시한 credential세션: 거절 / JWT: 만료/폐기 정책에 따름세션은 무효 기록에 의해 거절되고 JWT는 추가 폐기 정책이 필요하다같은 logout 표시에서도 서버 검증 결과가 다를 수 있다
특징세션 기반 인증토큰 기반 인증 (JWT)
상태 유지서버가 세션 상태 유지 (Stateful)서명 검증 가능; refresh·폐기는 상태 필요 가능
확장성공유 저장소 등 세션 공유 설계 필요검증 키·수명·폐기 정책 공유 필요
CORS쿠키·credentials 허용 필요Authorization 등 요청 헤더 허용 필요
모바일 앱어려움용이
보안세션 ID도 비밀로 보호; 서버가 만료·폐기 제어토큰 탈취 시 위험 (블랙리스트 필요)
주 사용처전통적인 웹 페이지, 단일 서버SPA, 모바일 앱, 마이크로서비스

세션과 JWT는 앱 종류만으로 결정하지 않고 검증, 폐기, 저장·전송 방식과 운영 요구를 함께 비교합니다.


권한 부여 구현 방식

인증된 사용자가 특정 자원에 접근하거나 특정 작업을 수행할 수 있는지 확인하는 과정입니다.

역할 기반 접근 제어

역할 기반 접근 제어 (RBAC: Role-Based Access Control)은 가장 흔하게 사용되는 권한 부여 방식입니다.

  • 개념: 사용자에게 역할(Role)을 부여하고, 각 역할에 특정 권한(Permission)을 할당합니다. 사용자가 접근할 수 있는 자원이나 수행할 수 있는 작업은 그 사용자의 역할에 따라 결정됩니다.
  • 예시
    • 역할: 관리자(Admin), 일반 사용자(User), 게스트(Guest)
    • 권한: 게시물 생성, 게시물 수정, 게시물 삭제, 사용자 관리
    • Admin 역할은 모든 권한을 가짐.
    • User 역할은 게시물 생성, 게시물 수정 권한을 가짐.
    • Guest 역할은 게시물 조회 권한만 가짐.
  • 구현 방법
    • 데이터베이스: users 테이블, roles 테이블, permissions 테이블, 그리고 이들을 연결하는 중간 테이블(예: user_roles, role_permissions)을 생성하여 관계를 정의합니다.
    • 백엔드 로직: API 엔드포인트에 접근할 때, 요청을 보낸 사용자의 역할을 확인하고, 해당 역할이 요청된 작업에 대한 권한을 가지고 있는지 검사합니다.
      • 예: DELETE /api/posts/:id 엔드포인트에 접근하는 사용자가 Admin 역할인지 확인.
      • Express.js에서는 미들웨어(Middleware)를 사용하여 특정 라우트에 접근하기 전에 권한을 검사하는 로직을 구현할 수 있습니다.
Express.js 권한 미들웨어 예시 (간략)
// app.js 또는 routes/auth.js

// 인증 미들웨어 (JWT 토큰 검증 후 req.user에 사용자 정보 추가)
const authenticateToken = (req, res, next) => {
    const authHeader = req.headers['authorization'];
    const token = authHeader && authHeader.split(' ')[1]; // Bearer token

    if (token == null) return res.set('WWW-Authenticate', 'Bearer').sendStatus(401); // 토큰 없음

    jwt.verify(token, process.env.ACCESS_TOKEN_SECRET, (err, user) => {
        if (err) return res.set('WWW-Authenticate', 'Bearer').sendStatus(401); // 유효하지 않은 토큰
        req.user = user; // req.user에 사용자 정보(id, role 등) 저장
        next();
    });
};

// 권한 부여 미들웨어 (특정 역할만 허용)
const authorizeRoles = (roles) => {
    return (req, res, next) => {
        if (!req.user || !roles.includes(req.user.role)) {
            return res.status(403).json({ message: 'Forbidden: You do not have the required role.' });
        }
        next();
    };
};

// 라우트에 미들웨어 적용
app.get('/api/admin-dashboard', authenticateToken, authorizeRoles(['admin']), (req, res) => {
    res.json({ message: 'Welcome to admin dashboard!', user: req.user });
});

app.post('/api/posts', authenticateToken, authorizeRoles(['admin', 'user']), (req, res) => {
    // 게시물 생성 로직
    res.status(201).json({ message: 'Post created.' });
});
예시

위 코드에서 검증 콜백이 유효한 { id: 7, role: 'user' }를 넘겼다고 가정합니다. authenticateToken은 req.user를 넣고 다음 미들웨어로 진행합니다. 그러나 authorizeRoles(['admin'])에 user가 없으므로 관리자 화면은 403으로 끝납니다. 같은 신원으로 게시물 생성의 ['admin', 'user']를 통과하면 원 핸들러가 201을 보냅니다. 로그인 성공과 모든 작업 허용은 다른 판단입니다.

이 코드는 흐름을 보여주는 간략 예시입니다. jwt와 app의 준비, 토큰 발급, 실제 검증 키와 비밀 관리, 만료·허용 알고리즘·발급자·대상 정책은 생략되어 있습니다. authHeader.split(' ')[1]은 Bearer 스킴 자체나 전체 헤더 형식을 검사하지 않으므로 운영용 파서로 그대로 복사하지 않습니다. JWT 검증의 알고리즘·발급자·대상 원칙과 만료 클레임의 의미를 설정에 연결해야 합니다. 또한 여기서는 req.user.role만 비교하므로 게시물의 소유자를 검사하는 인가 정책은 추가로 필요합니다.

독립 확인

① 헤더가 없는 요청, ② 검증 콜백이 오류를 반환하는 토큰, ③ 유효한 user의 관리자 화면 요청, ④ 유효한 admin의 게시물 생성 요청이 어디서 끝나는지와 상태를 써 보세요. ⑤ 헤더를 Basic good-user-token으로 바꿨는데 이 간략 코드의 검증 함수가 두 번째 값을 유효한 토큰으로 판정했다면, 스킴 오류를 이 코드가 스스로 잡을까요?

미들웨어 순서로 확인

①·②는 인가에 도달하지 않고 401과 WWW-Authenticate: Bearer를 보냅니다. ③은 인증 다음 역할 검사에서 403입니다. ④는 두 검사를 통과해 생성 핸들러에서 201입니다. ⑤는 두 번째 문자열만 추출하므로 스킴 오류를 놓치고 다음 단계로 진행합니다. 이는 토큰이 안전하다는 증거가 아니라 헤더 파싱을 강화할 지점을 찾아낸 결과입니다. 이 절의 401은 유효한 자격 증명을 요구하는 HTTP challenge와 함께 읽습니다.

서명된 토큰의 payload는 비밀 저장소가 아닙니다. 클라이언트가 자신의 토큰을 지워도 다른 곳에 복사된 토큰은 사라지지 않습니다. 서버 세션을 폐기하는 경우와 JWT 폐기 목록·짧은 수명·refresh 폐기를 사용하는 경우를 구별하고, 권한 변경을 언제 요청에 반영할지도 정해야 합니다.

속성 기반 접근 제어

속성 기반 접근 제어 (ABAC: Attribute-Based Access Control)은 RBAC보다 더 유연하고 세밀한 권한 부여 방식입니다.

  • 개념: 사용자, 자원, 환경 등 다양한 속성(Attribute)을 조합하여 접근 결정을 내립니다.
  • 예시: 오전 9시부터 오후 5시 사이에만 접근 가능한 A 부서의 팀장이 작성한 문서, IP 주소가 특정 범위 내에 있을 경우만 접근 가능한 파일 등.
  • 장점: 매우 유연하고 세밀한 제어 가능.
  • 단점: 구현 및 관리가 복잡하여 대규모 엔터프라이즈 환경에서 주로 사용됩니다.

비밀번호 보안 (다시 강조)

인증의 가장 기본적인 요소인 비밀번호 보안은 아무리 강조해도 지나치지 않습니다.

  • 해싱(Hashing): 비밀번호를 데이터베이스에 저장하기 전에 솔트와 계산 비용을 갖춘 비밀번호 전용 해시(예: bcrypt, scrypt)를 사용합니다. 신규 시스템의 Argon2id 우선 검토, scrypt 대안, 기존 bcrypt 호환 요구를 앞 절의 선택 원칙과 함께 확인합니다.
    • 솔트(Salt): 각 비밀번호마다 고유한 랜덤 값인 솔트를 추가하여 해싱합니다. 이를 통해 동일한 비밀번호라도 다른 해시 값을 가지게 하여 레인보우 테이블 공격 등을 방어할 수 있습니다.
    • 반복 횟수 증가: 해시 함수를 여러 번 반복하여 계산 시간을 늘려 무작위 대입 공격(Brute-force attack)을 어렵게 만듭니다.
  • 비밀번호 정책: 충분한 길이, 유출·흔한 비밀번호 차단 목록과 비밀번호 관리자 지원을 적용합니다. 임의의 문자 조합은 강제하지 않습니다.
  • 재사용 금지: 이전에 사용했던 비밀번호 재사용 금지.
  • 유출 시 변경: 정기 변경을 강제하지 않고 유출 근거가 있을 때 변경과 세션 폐기를 요구합니다.

인증·권한 부여 정리

정리 구간에서는 인증(신원 확인)과 권한 부여(행위 허용)를 분리해 설계하는 기준을 다시 확인합니다.

실제 API 요청에서는 인증 실패와 권한 부족을 다른 단계로 처리해야 응답 코드와 보안 로그가 선명해집니다.

이번 장에서는 웹 애플리케이션의 사용자 관리에서 가장 중요한 두 가지 개념인 인증(Authentication)과 권한 부여(Authorization)의 기초를 학습했습니다.

이번 절에서는 인증과 권한 부여의 차이, 세션 기반 인증과 토큰 기반 인증의 동작 방식, RBAC의 기본 구조를 정리했습니다.

Express.js 미들웨어 예시를 통해 접근 권한을 요청 처리 흐름에 연결하는 방식도 확인했습니다.

안전한 웹 서비스에서는 인증 방식, 권한 정책, 비밀번호 저장 방식, 세션 또는 토큰 수명 정책을 함께 관리해야 합니다.