노트인증과 인가
Authentication and Authorization
백엔드#security · 연결된 개념 12개
쉽게 말하면
인증은 공연장 입구에서 표와 신분증으로 '누구인지' 확인하는 거고, 인가는 안에서 손목밴드 색을 보고 'VIP석에 들어가도 되는지' 판단하는 거예요. 확인이 먼저, 허락이 그다음이죠.
비유의 한계 공연장은 입구만 지키면 될 것 같지만, 서버는 로그인한 사람이 남의 주문 ID로 조회하지 못하게 객체마다 소유를 확인해야 해요(IDOR). 버튼을 숨기는 건 인가가 아니고, 인가는 항상 서버에서 해요.
인증(authentication)은 "너는 누구냐"를 확인하는 것이고, 인가(authorization)는 "너는 이걸 해도 되냐"를 판단하는 것이다. 인증이 먼저고 인가가 그다음이다.
| 인증 | 인가 |
|---|
| 질문 | 누구인가 | 무엇을 할 수 있는가 |
| 예 | 로그인, 토큰 검증 | 관리자만 삭제, 작성자만 수정 |
| 실패 응답 | 401 Unauthorized | 403 Forbidden |
| 근거 | 비밀번호, 토큰, 키 | 역할(role), 권한, 소유 관계 |
- HTTP 상태 코드 이름이 헷갈리게 붙어 있다. 401의 이름은 Unauthorized지만 실제 뜻은 "인증이 안 됨"이고, 403이 "인증은 됐지만 권한 없음"이다
- 인증 수단: 세션 쿠키(세션 인증), 토큰(JWT), API 키, SSH(Secure Shell) 키(SSH 키: Ed25519와 RSA)
- 인가 수준: URL·메서드 단위(관리자 페이지), 객체 단위(내 글만 수정), 행 단위(행 수준 보안 (RLS))
프레임워크에서
- 스프링 시큐리티: 필터체인의 인증 필터가
SecurityContext에 사용자를 채우고, 이후 hasRole·@PreAuthorize로 인가한다
- DRF: authentication 클래스는 요청을 보낸 사용자가 누구인지 식별만 하고 요청을 막지 않는다. 허용 여부는 permission 클래스가 결정한다(DRF 인증과 권한)
- Django:
AuthenticationMiddleware가 request.user를 채운다(Django 미들웨어와 로그인 흐름)
흔한 실수
- 인증만 확인하고 객체 소유를 확인하지 않아, 로그인한 누구나 남의 주문 ID로 조회할 수 있다(IDOR, Insecure Direct Object Reference)
- 프론트엔드에서 버튼을 숨기는 것으로 인가를 대신한다. 인가는 항상 서버에서 한다(브라우저 요청과 서버 간 요청)
- 403이어야 할 때 404를 돌려주면 리소스 존재 자체를 숨길 수 있다. 의도적으로 고른다
비밀번호를 안전하게 저장하는 문제는 비밀번호 저장: 인코딩·암호화·해싱을 본다.
출처: MDN: 401 Unauthorized · MDN: 403 Forbidden · OWASP Top 10:2025 A01: Broken Access Control
연결된 개념
이 노트를 가리키는 문서
뜻이 가까운 노트
- CSRF
CSRF(Cross-Site Request Forgery, 사이트 간 요청 위조)는 로그인한 사용자가 악성 사이트를 방문했을 때, 그 사이트가 사용자의 브라우저를 시켜 사용자 모르게 원래 사이트에 요청을 보내게 하는 공격이다. 공격자는 토큰을 훔치지 않는다. 브라우저가 쿠키를 알아서 붙여 준다는 점을 이용한다.
- Django의 CSRF 방어
Django는 CsrfViewMiddleware로 CSRF(Cross-Site Request Forgery)를 막는다. 기본 아이디어는 Double Submit Cookie, 즉 쿠키에 든 CSRF 값과 요청에 함께 보낸 값을 비교하는 것이고, 여기에 토큰 마스킹(token masking)과 Origin·Referer 검사를 더한다.
- XSS
XSS(Cross-Site Scripting)는 공격자가 넣은 스크립트가 내 사이트의 출처(origin) 권한으로 사용자 브라우저에서 실행되는 공격이다. 같은 출처의 코드로 돌기 때문에 same-origin-policy가 막아 주지 못한다. 그 스크립트는 페이지를 바꾸고, 로그인한 사용자 행세를 하며 요청을 보내고, JS가 읽을 수 있는 데이터(localStorage의 토큰 등)를 빼 갈 수 있다.
- 동일 출처 정책
한 출처에서 실행된 스크립트가 다른 출처의 데이터를 읽지 못하게 막는 브라우저의 기본 보안 규칙. 다른 출처에 요청을 보내는 것은 대체로 허용하고, 응답을 읽는 것을 막는다.
- DRF API 테스트
DRF는 장고 테스트 위에 API 요청을 편하게 보내는 APITestCase와 APIClient를 제공한다. 장고 테스트 러너(test runner)는 테스트용 DB를 따로 만들고, 각 테스트를 트랜잭션으로 감싸 끝나면 되돌리므로 실제 데이터를 건드리지 않는다.