프론트엔드 개발에서 인증(Authentication)과 인가(Authorization)는 보안과 관련된 매우 중요한 개념이다. 이 둘은 종종 혼동되지만, 각각의 역할이 다르며, 그 과정에서 발생할 수 있는 보안 리스크도 다르다.
(1) 인증(Authentication)
인증은 사용자가 누구인지를 확인하는 과정이다. 일상 생활에서 주민등록증을 통해 신분을 입증하는 것과 같이 "당신이 누구인가?"를 묻는 단계이다. 인증을 통해 시스템은 사용자가 주장하는 인물 본인이 맞는지를 확인하게 된다.
로그인 시나리오로 보는 인증
- 사용자 입력: 사용자는 사용자 이름(또는 이메일)과 비밀번호를 입력
- 서버 요청: 프론트엔드는 이 정보를 서버에 전달하여 사용자가 올바른지 확인
- 서버 검증: 서버는 데이터베이스에 저장된 정보와 사용자가 입력한 정보를 비교. 올바르다면, 사용자는 인증됨
- 토큰 발급: 성공적인 인증 후, 서버는 인증 토큰(예: JWT)을 발급(이 토큰은 사용자가 이후의 요청에서 자신의 신원을 증명하는 데 사용됨)
- 토큰 저장: 프론트엔드는 이 토큰을 로컬 스토리지, 세션 스토리지, 또는 쿠키에 저장
1) 인증 받는 유형
그렇다면 사용자가 인증을 받는 유형에는 어떠한 것이 있을까?
- 비밀번호 기반 인증: 가장 일반적인 방식으로, 사용자가 비밀번호를 통해 인증
- 2단계 인증: 비밀번호 외에 추가적인 인증 방법을 요구(예를 들어, SMS로 전송된 코드 입력)
- 생체 인식 인증: 지문, 안면 인식, 홍채 인식 등 사용자의 신체적 특징을 이용한 인증 방법
- SSO(Single Sign-On): 사용자가 한 번의 로그인으로 여러 애플리케이션에 접근할 수 있는 인증 방식(OAuth2, SAML 등을 사용)
2) 보안 리스크
위에서 살펴본 인증 방식들은 각기 다른 보안 리스크를 수반한다.
먼저, 비밀번호 노출의 위험이 있다. 사용자의 비밀번호가 유출되면 공격자는 이를 이용해 사용자의 계정에 접근할 수 있다. 이를 방지하기 위해 SSL/TLS를 사용하여 전송 중인 데이터를 암호화하고, 서버에서는 비밀번호를 해시 처리하여 저장해야 한다.
다음으로, 토큰 탈취의 위험이 있다. 인증 토큰이 노출되면 공격자는 이를 이용해 인증된 사용자인 것처럼 행동할 수 있다. 토큰 탈취는 주로 XSS(Cross-Site Scripting) 공격을 통해 이루어진다. 이러한 위험을 줄이기 위해 토큰은 안전하게 저장되어야 하며, HttpOnly 쿠키를 사용해 자바스크립트로 접근할 수 없도록 해야 한다.
또한, 무차별 대입 공격의 위험이 있다. 공격자는 자동화된 도구를 사용해 여러 비밀번호를 시도하여 사용자의 계정을 해킹하려 할 수 있다. 이를 방지하기 위해서는 로그인 시도 제한, CAPTCHA 등을 사용하여 무차별 대입 공격을 차단해야 한다.
이와 같이 다양한 인증 방식과 보안 리스크를 이해하고, 적절한 보안 조치를 취하는 것이 중요하다.
3) 프론트엔드에서의 인증 처리
(2) 인가(Authorization)
인가는 인증된 사용자가 특정 리소스나 기능에 접근할 수 있는 권한이 있는지를 확인하는 과정이다. 즉, "당신이 무엇을 할 수 있는가?"를 묻는 단계이다.
인가 과정
- 인증된 요청: 인증된 사용자는 프론트엔드를 통해 서버에 요청을 보냄
- 권한 확인: 서버는 요청을 받은 후, 해당 사용자가 요청한 리소스에 접근할 권한이 있는지 확인(이 정보는 일반적으로 역할 기반 접근 제어(Role-Based Access Control, RBAC)나 권한 목록(Access Control List, ACL)을 통해 관리됨)
- 응답: 권한이 있다면 서버는 요청을 처리하고, 그렇지 않다면 접근이 거부됨
1) 인가의 유형
그렇다면 인가의 유형에는 어떤 것이 있을까?
- 역할 기반 접근 제어(Role-Based Access Control, RBAC): 사용자가 가진 역할에 따라 접근 권한을 부여. 예를 들어, "관리자", "사용자" 등으로 역할을 나누어 권한을 다르게 설정
- 권한 기반 접근 제어(Permission-Based Access Control, PBAC): 사용자의 개별 권한에 따라 접근을 제어. 즉, 특정 사용자에게 특정 리소스에 대한 접근을 허용하거나 금지할 수 있음
- 속성 기반 접근 제어(Attribute-Based Access Control, ABAC): 사용자의 속성(예: 부서, 위치, 시간 등)에 따라 권한을 부여. 예를 들어, "영업부의 근무시간 동안만 접근 가능" 등의 정책을 적용할 수 있음
2) 보안 리스크
그렇다면 인가와 관련된 보안 리스크에는 어떠한 것이 있을까?
먼저 권한 상승 공격의 위험이 있다. 사용자가 자신의 권한을 초과하여 더 높은 권한을 가진 리소스에 접근하려는 시도가 있을 수 있다. 이를 방지하기 위해 서버는 모든 요청에 대해 철저한 권한 검사를 수행해야 한다.
둘째, 불충분한 검증의 위험이 있다. 인가 검사가 제대로 이루어지지 않으면 사용자가 자신이 접근할 수 없는 데이터나 기능에 접근할 수 있다. 특히 프론트엔드에서 인가 검사가 제대로 이루어졌는지를 확인하는 것은 어려우므로, 이 검증은 반드시 서버 측에서 수행되어야 한다.
셋째, 민감한 데이터 노출의 위험이 있다. 인가가 제대로 관리되지 않으면 민감한 데이터를 보호할 수 없게 되어 데이터 유출 위험이 커진다. 이러한 리스크를 방지하기 위해서는 철저한 인가 관리와 보안 검증이 필요하다.
3) 프론트엔드에서의 인가 처리
~~
(3) 인증과 인가의 결합 및 보안
프론트엔드에서는 인증과 인가가 긴밀히 연관되어 작동한다. 인증이 완료되면, 사용자는 토큰을 통해 자신의 신원을 증명하고, 서버는 이 신원을 바탕으로 인가를 수행한다. 이 과정에서 다양한 보안 리스크가 발생할 수 있으므로, 다음과 같은 보안 조치가 필요하다.
보안 조치
보안 토큰 사용: OAuth2와 같은 표준 프로토콜을 통해 토큰을 안전하게 관리
- 안전한 저장소: 인증 토큰을 로컬 스토리지 대신 쿠키(HttpOnly, Secure 플래그 설정)로 저장하여 XSS 공격을 방지
- 민감한 데이터 최소화: 최소한의 데이터를 클라이언트에 노출하며, 민감한 데이터는 서버에서만 관리
- 모니터링 및 로깅: 모든 인증 및 인가 요청을 로깅하여 비정상적인 활동을 모니터링
이렇게 인증과 인가 과정에서 발생할 수 있는 보안 리스크를 사전에 인지하고, 이를 완화하기 위한 조치를 취하는 것이 중요하다.
이처럼 인증과 인가는 시스템 보안의 근간을 이루므로 각각의 과정에서 발생할 수 있는 보안 리스크를 이해하고 적절한 조치를 취하는 것이 중요하다. 인증은 사용자의 신원을 확인하는 것이고, 인가는 사용자가 접근할 수 있는 리소스나 기능을 결정하는 것이라는 점을 기억해야 한다. 시스템 설계 시 이 두가지를 명확히 구분하여 관리하는 것이 보안성을 높이는 핵심이다.