1. 인증과 인가
인증: 사용자가 누구인지 확인하는 과정
인증은 통해서 사용자가 누구인지 확인하고 그 후에 토큰을 발급해서 매 요청마다 다시 인증하지 않고 토큰을 사용해서 사용자를 식별한다.
토큰으로 사용자를 식별하기 위해서는 정보를 저장해야 하는데 서버 별도의 저장소에 저장해서 토큰으로 매핑 하거나 토큰 자체에 사용자 식별 정보를 저장한다.
1.1. 외부 저장소에 식별 정보 저장
서버에 토큰과 사용자 식별 정보를 DB또는 레디스같은 별도 저장소에 보관할 수 있다.
그 때 저장되는 데이터는
- 토큰
- 사용자 식별자
- 생성 시간
- 최근 사용 시간
- 그 외 유효 시간, 클라이언트 버전 등 기타 데이터
등이 저장된다.
별도 저장소 사용은 보통 서버가 여러 대인 경우, 세션 공유가 필요하거나 서버 재시작 시에도 인증 상태를 유지해야 할 때 사용되는 방식이다.
외부 저장소 자체가 비용이 발생하는 대신에 많은 양의 데이터를 안전하게 저장할 수 있기 때문이다.
서버 메모리에 저장할 수 있다.
톰캣과 같은 서블릿 컨테이너는 메모리에 세션 객체를 저장할 수 있다.
세션은 고유의 세션 ID를 생성하는데 이게 바로 토큰에 해당한다.
서버마다 서로 다른 토큰 집합을 저장하기 때문에 위 방식에는 고정 세션이 필요하다.
세션 방식에는 2가지 단점이 있는데 하나는 서버를 재시작하면 토큰 데이터가 사라지는 점, 두번째로 생성할 수 있는 세션 개수가 메모리 크기에 제한을 받는다는 점이다.
1.2. 토큰 자체에 식별 정보 저장
클라이언트 자체에 저장된 토큰으로 서버는 사용자를 식별한다.
이 방식은 토큰만 있으면 사용자가 누구인지 확인이 가능하다.
별다른 저장 공간이 필요 없다는 것이다.
다만 전송하는 데이터의 양이 외부 저장 방식보다 많아지기 때문에 트래픽이 증가하고 서버에서 토큰 데이터를 제어할 수 없는 점도 단점이다.
토큰이 오래 되어도 서버는 자체적으로 토큰을 삭제할 수 없다는 것이다.
이 부분은 계정 정시 시 즉시 차단이 어려운 점과도 일맥상통한 점이 있다.
이 단점은 토큰을 보관할 때 유효 시간을 설정하는 방법으로 보완할 수 있다.
토큰 송수신은 두가지 방법을 사용할 수 있다.
쿠키: 쿠키를 사용해서 토큰 전송
- 브라우저가 자동으로 전송하므로 구현이 단순하다.
- HttpOnly, Secure, SameSite 옵션을 통해 보안을 강화할 수 있다.
- 다만 CSRF 공격에 취약할 수 있어 별도의 CSRF 대응이 필요하다.
헤더: 특정 이름을 갖는 헤더를 사용해서 토큰 전송
- CSRF 공격에 상대적으로 안전하다.
- 모바일 앱, API 서버 등 다양한 클라이언트에서 사용하기 좋다.
- 클라이언트가 직접 토큰을 관리해야 하므로 구현 복잡도가 조금 높다.
보안과 편의를 위해 사용하는 토큰이니만큼 토큰 자체의 보안도 중요하다.
토큰을 탈취당하면 탈취한 클라이언트는 원래 토큰 소유자처럼 페이지를 이용할 수 있다.
토큰 탈취에 따른 보완 문제를 완화하는 방법은 토큰에 유효 시간을 설정하는 것이다.
- 토큰 생성 시전을 기준으로 제한 시간 설정
- 마지막 접근 시간을 기준으로 토큰 유효 시간 설정
토큰 재발급 방식도 있는데 액세스 토큰과 리프레시 토큰을 사용하는 방법이다.
액세스 토큰은 말 그대로 인증된 사용자임을 확인하기 위해서이다.
리프레시 토큰은 유효기간이 짧은 액세스 토큰이 만료되면 리프레시 토큰을 보고 다시 액세스 토큰을 발급해줘서 인증 상태를 유지할 수 있다.
인가: 사용자에게 자원에 접근할 수 있는 권한 부여
인가는 요청한 기능을 실행할 권한이 있는지 확인하는 역할을 한다.
이를테면 로그인 했다고 다른 사람의 정보를 볼 수 없는 것 처럼 로그인한 계정의 정보만 볼 수 있도록 제한하는 것이 인가에 해당한다.
사용자가 접근할 수 있는 기능을 관리하기 위한 모델을 접근 제어 모델이라고 한다.
대표적으로 역할 기반 접근 제어 모델이 있다.
역할 기반 접근 제어 모델은 역할별로 실행 가능한 기능 집합을 할당하고 사용자에게 역할을 부여한다.
역할 각각에 허용된 기능이 있고 사용자마다 허용된 기능만 사용하는 것이다.
2. 데이터 암호화
유출되면 가장 큰 피해로 이어질 수 있는 데이터가 있는데 대표적으로 로그인 아이디와 비밀번호다.
해당 정보가 유출되면 그 계정으로 쉽게 로그인할 수 있고 로그인에 성공하면 다른 정보를 보거나 계정에 묶인 다양한 기능을 사용할 수 있다.
이런 위험을 줄이기 위해서 데이터를 저장할 때 비밀번호 등을 암호화 하는 것이다.
데이터가 유출되어도 암호화된 데이터는 곧바로 사용할 수 없고 그 안에 사후 대응을 할 수 있는 시간을 벌 수 있다.
암호화 방식에는 단방향 암호화와 양방향 암호화 방식이 있다.
2.1. 단방향 암호화
암호화한 데이터를 복호화 할 수 없는 암호화 방식이다.
대표적으로 SHA-256, MD5, BCrypt 등이 있다.
값의 비교는 전달받은 데이터를 저장에 사용한 암호화 방식과 동일하게 암호화 시켜서 암호화된 데이터를 서로 비교하는 방식이다.
단방향 암호화는 복호화를 할 수 없기 때문에 기존에 정보를 분실했다면 새로 저장시켜야 한다.
Salt라는 보안 알고리즘이 있다.
보통 암호화를 한다면 항상 동일 원본값에 동일한 암호화 값이 생성된다.
만약 해커가 다양한 문자열과 해시 값을 미리 계산해서 가지고 있다면 일부 암호화 된 비밀번호는 원본 값을 유추할 수 있다.
각 사용자마다 각각의 Salt값으로 암호화를 진행한다면 원본 값을 유추하는데 더 많은 노력이 들 것이다.
2.2. 양방향 암호화
암호화와 복호화 모두 가능한 방식이다.
SSH프로토콜, AES, RSA 등이 있다.
양방향 암호화는 대칭 키 방식과 비대칭 키 방식으로 또 나뉜다.
2.2.1 대칭 키 방식
암호화와 복호화에 동일한 키를 사용한다.
만약 키가 유출되면 누구나 암호화된 데이터를 복호화할 수 있다.
대칭 키 방식의 대표적인 알고리즘으로 AES가 있다.
해당 알고리즘을 사용할 때 키와 IV(초기화 백터) 두 값을 생성해서 공유한다.
키만을 사용하면 항상 같은 원본 값에 같은 암호화 값이 만들어 지는데 여기서 IV가 사용된다.
IV는 임의의 바이트 배열로 암호화할 때 함께 사용되면 같은 키를 쓰더라도 결과가 매번 달라진다.
복호화할 때도 IV가 필요하기 때문에 키와 함께 IV도 안전하게 보관되어야 한다.
2.2.2. 비대칭 키 방식
암호화와 복호화에 서로 다른 키를 사용한다.
해당 방식은 공개 키와 개인 키를 생성하는데 공개 키는 암호화에, 개인 키는 복호화에 사용된다.
키 소유자는 각 키를 쌍으로 생성한 뒤에 데이터 송신자에게 공개 키를 제공한다.
공개 키로 암호화한 데이터는 개인 키로만 복호화할 수 있기 때문에 공개 키가 유출되더라고 암호화한 데이터를 복호화할 수 없다.
비대칭 키 방식으로 RSA 알고리즘이 있다.
공개 키는 바이트 배열을 문자열로 공유하거나 바이트 배열 자체를 파일로 저장해서 공유한다.
개인 키 또한 바이트 배열로 저장한다.
* 사용자 인증에서 비대칭 키를 사용하는 간단한 흐름
- 서버는 공개 키와 개인 키 한 쌍을 생성한다.
- 공개 키는 외부에 공개하고, 개인 키는 서버만 보관한다.
- 사용자는 서버의 공개 키로 데이터를 암호화해서 전송한다.
- 서버는 자신의 개인 키로 해당 데이터를 복호화한다
3. HMAC을 이용한 데이터 검증
클라이언트가 데이터를 보내면 이 데이터가 유효한 값인지, 중간에 위변조 당하지 않았는지 확인할 수단이 필요한데 이 때 HMAC을 주로 사용한다.
HMAC은 Hash based Message Authentication Code의 약자로 메시지의 무결성과 인증을 보장하기 위해 사용하는 암호화 기술이다.
메시지의 발신자와 수신자는 둘만 알고 있는 비밀 키를 공유한다.
때문에 HMAC 자체는 간단하게 메시지 보안을 유지할 수 있으나 비밀 키가 유출 되면 보안이 취약해진다.
4. 방화벽으로 필요한 트래픽만 허용하기
서버가 외부에 노출되면 다양한 공격이 들어올 수 있다. 이를 방지하기 위해서 필요한 만큼만 네트워크 접근을 허용해야 한다.
가장 기본적인 네트워크 접근 차단은 방화벽을 통해 이뤄진다.
방화벽은 흔히 인바운트 트래픽, 아웃바운드 트래픽으로 이뤄진다.
기본적으로 인바운트 트래픽은 필수적인 트래픽만 허용하고 나머지는 차단한다.
내부 서버를 외부로의 노출을 최대한 막아야 하기 때문이다.
아웃바운드 역시 가능한 필수만 허용하고 나머지는 차단한다.
아웃바운드를 모두 허용하면 서버가 해킹당했을 때 해커의 중간 경유지로 악용될 수 있기 때문이다.
방화벽은 단순히 트래픽 제어 이외에 DDoS나 포트 스캔 같은 네트워크 공격을 차단하는 기능도 제공한다.
5. 감사 로그(audit log)남기기
감사 로그는 특정 작업, 절차, 사건 또는 장치에 영향을 주는 활동의 순서를 입증하는 보안 관련 기록이다.
대표적인 감사 로그 대상으로는
- 사용자의 로그인/로그아웃 내역
- 암호 초기화 등 설정 변경 내역
- 환자 기록을 조회한 의료진 정보
- 계약서의 수정 이력
등이 있다.
이런 로그는 보안이 중요한 시스템에서 사고가 발생했을 때 문제 해결에 큰 도움이 된다.
6. 데이터 노출 줄이기
데이터가 기능에 필요한 것 보다 더 많이 표출된다면 그 것 자체가 보안의 취약점이 된다.
만약 해커가 관리자 정보를 탈취해서 백오피스에 접근이 가능하다면 사용자 정보를 탈취할 수 있다.
이 때 고객 정보를 한번에 다양한 정보를 볼 수 있다면 피해는 매우 클 것이다.
이러한 상황을 대비하기 위해 데이터 자체를 마스킹 처리하거나 한번에 볼 수 있는 데이터를 수 자체를 줄여서 피해를 줄일 수 있다.
로그 메시지 또한 조심해야 한다.
로그 데이터 자체에 민감 정보가 평문으로 표시된다면 로그 자체로 보안 위협이 될 수 있다.
7. 비정상 접근 처리
사용자가 평소와 다른 행동 패턴을 보이면 비정상 접근으로 판단하고 해당 내용을 사용자에게 알려주는 서비스가 있다.
예를들어
- 평소와 다른 장소에서 로그인
- 평소와 다른 기기로 로그인
- 로그인에 여러 차례 실패함
이 3가지는 시스템적으로 보안을 강화하면 계정 탈취 등 보안 문제에 좋다.
8. 시큐어 코딩
사용자 입력이 가능한 부분으로 SQL인젝션 공격이 들어오거나 url로 직접 요청을 보내서 JS validation check를 피할 수도 있다.
서버 개발을 진행하면서 사용자가 전송한 값이 올바르다 가정하지 말고 클라이언트 단에서 체크한 값을 서버에서도 무시하지 말고 서버에서도 다시 검증해야 한다.
이외에도 신경써야 하는 항목이 있다.
- 개인 정보/민감 정보 암호화: 인증 정보 뿐 만 아니라 고유 식별 정보도 암호화 해야 한다.
- 에러 메시지에 시스템 정보 미노출: 에러 메시지에 내부 IP나 DB IP같은 정보 노출되지 않도록 한다.
- 보안 통신: HTTPS처럼 정송 데이터를 암호화 한다.
- CORS 설정: 허용된 도메인만 서버 자원 접근 가능하도록 제한한다.
- CSRF 대응: 타 사이트에서 위조 공격 들어오는 것을 막는다.
9. 개인 보안
개발자는 아양한 서버에 연결할 수 있다.
권한에 따라 DB에 접속해서 다양한 쿼리도 실행할 수 있다.
개발자가 접근할 수 있는 시스템에 많은 만큼 개발자 개인의 PC에도 보안이 필요하다.
출처가 불분명한 파일 다운받는 것, 의심스러운 이메일 첨부 파일 실행 등의 일은 지양해야 한다.
물리적인 보안도 무시할 수 없다.
자리를 비울 때 화면 보호기를 실행하거나 중요 사이트 로그인한 상태에서 자리를 비우지 않는 등 PC 외적으로도 주의가 필요하다.
'책 리뷰 > 주니어 백엔드 개발자가 반드시 알아야 할 실무 지식' 카테고리의 다른 글
| 7장. IO병목, 어떻게 해결하지 (0) | 2026.01.18 |
|---|---|
| 6장. 동시성, 데이터가 꼬이기 전에 잡아야 한다 (0) | 2025.12.15 |
| 5장. 비동기 연동, 언제 어떻게 써야 할까 (0) | 2025.12.07 |
| 4장. 외부 연동이 문제일 때 살펴봐야 할 것들 (0) | 2025.11.29 |
| 3장. 성능을 좌우하는 DB설계와 쿼리 (0) | 2025.11.02 |