개념
인증(Authentication)과 인가(Authorization)는 다르다
두 단어가 비슷해 보이지만 완전히 다른 질문에 답한다.
| 용어 | 질문 |
|---|---|
| 인증(Authentication) | 당신은 누구인가? (로그인) |
| 인가(Authorization) | 당신은 이걸 할 권한이 있는가? (권한 확인) |
로그인은 됐는데(인증 성공) 관리자 페이지에는 못 들어가는 것(인가 실패)은 정상 동작이다. 이 둘을 구분 못 하면 "로그인이 안 된다"는 부정확한 결함 리포트가 나온다 — 실제로는 로그인은 됐지만 권한이 없는 것일 수 있다(레슨 2의 401 vs 403 상태 코드와 연결된다).
세션 기반 인증
로그인에 성공하면 서버가 사용자를 식별하는 값(세션 ID)을 만들어 브라우저에 쿠키로 저장시킨다. 이후 요청마다 브라우저가 이 쿠키를 자동으로 함께 보내면, 서버는 "이 쿠키를 가진 사람이 로그인한 사용자다"라고 판단한다.
로그인 성공 → 서버가 세션 생성 → 쿠키로 세션 ID 전달
→ 이후 요청마다 쿠키 자동 첨부 → 서버가 세션 확인세션은 서버가 상태를 기억해야 한다(서버 메모리나 DB에 세션 정보 저장) — 이걸 "상태 유지(Stateful)" 방식이라 부른다.
토큰 기반 인증 (JWT)
서버가 상태를 기억하지 않고, 로그인 성공 시 정보 자체를 담은
토큰(JWT: JSON Web Token)을 발급한다. 이후 요청마다 이 토큰을
Authorization 헤더(레슨 2)에 담아 보내면, 서버는 토큰 안의 서명을
검증해서 신뢰할 수 있는지 확인한다 — 별도로 저장된 세션을 찾아볼
필요가 없다("상태 없음, Stateless" 방식).
로그인 성공 → 서버가 토큰 발급(서명 포함) → 클라이언트가 토큰 보관
→ 이후 요청마다 Authorization 헤더에 토큰 첨부 → 서버가 서명 검증토큰에는 만료 시간이 들어있는 경우가 많아서, "로그인한 지 오래돼서 토큰이 만료됐다"는 것도 흔한 버그 원인 중 하나다.
OAuth — 다른 서비스에 인증을 위임하기
"Google로 로그인" 버튼을 눌러본 적이 있을 것이다. OAuth는 우리 서비스가 직접 비밀번호를 다루지 않고, Google 같은 신뢰할 수 있는 제3자에게 "이 사용자가 진짜 본인인지" 확인을 위임하는 방식이다.
사용자가 "Google로 로그인" 클릭
→ Google 로그인 화면으로 이동(우리 서비스가 비밀번호를 보지 않음)
→ Google이 인증 성공 알림(코드)을 우리 서비스에 전달
→ 우리 서비스가 그 코드로 사용자 정보를 받아옴인증·인가 관련 흔한 버그 지점
- 토큰 만료 처리가 없어서, 만료된 토큰으로도 계속 요청이 성공한다 (보안 결함)
- 인가 검사를 프론트엔드에서만 하고 서버에서 하지 않아서, API를 직접 호출하면 권한 없는 데이터에 접근된다(모듈 5 레슨 9의 신뢰 경계와 연결)
- 로그아웃해도 이전에 발급된 토큰이 여전히 유효하다
실무에서 왜 필요한가
"로그인이 안 돼요"라는 버그 리포트의 원인은 실무에서 세션 만료, 토큰 오류, 권한 부족처럼 완전히 다를 수 있다. 인증·인가 개념을 구분해서 이해하면, 결함 리포트의 제목부터 "세션 만료 후 재로그인 없이 요청 시 401 응답"처럼 정확하게 쓸 수 있다. 또한 인가 검사가 프론트엔드에만 있고 서버에 없는 경우는 실제 보안 사고로 이어지는 흔한 패턴이라, 이걸 알아채는 QA는 보안 관점에서도 가치가 크다.
실습 과제
과제 1 — 인증 vs 인가 판단하기 (10분)
다음 세 상황이 인증 실패인지 인가 실패인지 판단한다.
- 아이디/비밀번호를 잘못 입력해 로그인이 거부됐다
- 일반 회원이 관리자 전용 API를 직접 호출했더니 403이 떴다
- 로그인 후 1시간 뒤 요청했더니 401이 떴다
과제 2 — 인가 검사 위치 점검하기 (15분)
"할인 쿠폰 관리 메뉴는 관리자만 접근 가능하다"는 기능이 있다고 하자. 이 인가 검사가 프론트엔드(버튼을 안 보여줌)에만 있고 서버 API에는 없다면 어떤 방법으로 우회 접근이 가능할지, 그리고 이걸 어떻게 테스트로 확인할 수 있을지 적는다.
자가 체크리스트
- 인증과 인가의 차이를 예시로 설명할 수 있다
- 세션 기반 인증과 토큰(JWT) 기반 인증의 차이를 설명할 수 있다
- OAuth가 왜 비밀번호를 직접 다루지 않는 방식인지 설명할 수 있다
- 인가 검사가 프론트엔드에만 있을 때 생기는 보안 위험을 설명할 수 있다
흔한 실수
- 인증 실패와 인가 실패를 구분하지 않고 뭉뚱그려 "로그인 문제"로 리포트한다. 401(인증)과 403(인가)은 원인과 대응이 다르다.
- 프론트엔드에서 버튼이 안 보이면 그 기능이 완전히 막혔다고 가정한다. 서버 API를 직접 호출하는 인가 우회 가능성을 확인해야 한다.
- 토큰 만료 시나리오를 테스트하지 않는다. 만료 처리가 빠지면 탈취된 토큰이 영구적으로 유효한 심각한 보안 결함이 될 수 있다.
참고 자료
- MDN — HTTP 인증 — 인증 헤더와 방식의 공식 레퍼런스
- OAuth 2.0 공식 사이트 — OAuth 흐름의 공식 설명
- jwt.io — JWT 구조와 동작 원리를 시각적으로 확인할 수 있는 자료