서버가 클라이언트 인증을 확인하는데는 크게 쿠키, 세션, 토큰 3가지 방법이 있다.
토큰(Token)
개념: 토큰은 인증을 위한 권한 부여에 사용되는 문자열로, 보통 사용자 인증 후 서버로부터 발급받는다. 이후 클라이언트가 서버에 요청을 보낼 때마다 이 토큰을 함께 전송하여 인증을 유지한다.
장점: 토큰 기반 인증은 상태를 서버에 저장할 필요가 없기 때문에 서버의 부하를 줄일 수 있다. 또한 클라이언트와 서버의 독립성을 높여 분산 환경에서도 쉽게 확장할 수 있다.
단점: 토큰은 클라이언트에 저장되므로 보안에 취약할 수 있다. 또한 토큰이 서버에 저장되지 않기 때문에 토큰 자체를 변경할 수 있는 방어책이 필요하다.
세션(Session)
개념: 세션은 클라이언트와 서버 간의 상태를 유지하기 위한 방법으로, 서버에서 클라이언트마다 고유한 식별자를 생성하여 클라이언트의 요청을 식별한다.
장점: 세션은 서버에 저장되므로 클라이언트에 비해 상대적으로 안전하다. 또한 서버 측에서 세션 데이터를 관리할 수 있어 보안적인 이점이 있다.
단점: 세션은 서버에 저장되기 때문에 서버에 부하를 줄 수 있다. 또한 분산 환경에서 상태를 관리하는 것이 어려울 수 있다.
쿠키(Cookie)
개념: 쿠키는 클라이언트의 로컬 브라우저에 저장되는 작은 데이터 조각으로, 클라이언트와 서버 간의 상태를 유지하기 위해 사용된다.
장점: 쿠키는 클라이언트 측에 저장되기 때문에 서버에 부하를 줄일 수 있다. 또한 만료 날짜를 설정하여 지속적으로 사용할 수 있다. 쿠키는 상대적으로 쉽게 구현할 수 있고, 브라우저에서 자동으로 처리되기 때문에 편리하다.
단점: 쿠키는 클라이언트에 저장되기 때문에 보안에 취약할 수 있다. 또한 쿠키의 용량이 제한되어 있어 큰 양의 데이터를 저장하기에는 적합하지 않을 수 있다.
✏️ HTTP 프로토콜의 무상태성
HTTP 프로토콜은 무상태성(Stateless) 프로토콜이다.
-> 이는 '각각의 요청이 서로 독립적이며 이전 요청의 상태를 기억하지 않는다!'는 것을 의미한다. 즉, 서버는 각각의 요청을 독립적으로 처리하고 응답을 보내며 이전 요청에 대한 상태를 유지하지 않는다.
-> 따라서 서버와 클라이언트 연결 유지를 구현하기 위해 서로 인식할 수 있는 식별 데이터가 필요하다. 이게 바로 쿠키 데이터 조각이다.
JWT(토큰)은 JSON Web Token의 약자로, 정보를 안전하게 전송하기 위한 토큰 기반의 인증 방식이다. JWT는 클레임(claim_JWT에서 사용되는 정보 조각 = 사용자에 대한 정보) 기반으로 되어 있어 페이로드에 클레임 정보를 담고 있으며, 디지털 서명을 통해 검증된다. 주로 웹 토큰은 사용자 인증 및 정보 교환에 사용된다.
✏️ JWT 토큰 사용 이유:
- 상태를 저장하지 않음: 서버에 상태를 저장할 필요 없이 토큰 자체가 사용자 인증 및 권한 부여에 필요한 모든 정보를 포함.
- 확장성: 토큰은 분산 시스템에서 쉽게 확장할 수 있으며, 여러 서비스나 마이크로서비스 간에 통합이 용이.
- 보안: JWT 토큰은 디지털 서명을 통해 검증되므로 위조가 어렵다.
클라이언트가 로그인을 요청하면 서버는 사용자를 인증하고, 토큰을 발급하여 클라이언트에게 전달 -> 클라이언트는 이 토큰을 이후의 요청에서 함께 전송하여 인증을 유지.
👉 이번 슬램톡 프로젝트에서는 서버에 부하를 줄이고 정보를 안전하게 전송하기 위해 JWT 토큰 방식을 사용했다.
✏️ XSS(Cross-Site Scripting) 공격이란?
웹 애플리케이션에서 발생하는 보안 취약점 중 하나로, 공격자가 제공한 악의적인 스크립트 코드가 웹 페이지에 삽입되어 실행되는 공격이다. 이를 통해 공격자는 사용자의 브라우저에서 악의적인 행동을 수행하게 하거나, 사용자의 개인 정보를 탈취할 수 있다.
- XSS 공격의 주요 유형
- 저장형 XSS (Stored XSS): 공격자가 악성 스크립트를 데이터베이스나 다른 저장소에 저장하여 이를 웹 페이지에 표시될 때 실행되게 함.
- 반사형 XSS (Reflected XSS): 공격자가 악성 링크를 통해 피해자에게 전송하고, 피해자가 해당 링크를 클릭할 때 실행되는 스크립트를 주입.
✔️ XSS 방지하는 방법
이스케이프(Escape) : 특수 문자나 예약된 문자를 특별한 의미로 해석되지 않고 문자 그대로 해석되도록 만드는 과정
✏️ 렌더링 엔진(Rendering Engine)이란?
웹 브라우저가 HTML 문서를 렌더링하여 사용자에게 화면에 보여주는 역할을 담당하는 소프트웨어 컴포넌트
-> HTML 문서를 파싱하여 DOM(Document Object Model) 트리로 변환하고, CSS 스타일을 적용하여 레이아웃을 구성하고, JavaScript 코드를 실행하여 동적인 기능을 처리. ex_Webkit, Blink, ...
✏️ CSRF 공격이란?
CSRF(Cross-Site Request Forgery_사이트 간 요청 위조) 공격은 인증된 사용자의 웹 애플리케이션 요청을 특정 웹 사이트에서 사용자의 동의 없이 보내는 공격이다. 이를 통해 공격자는 피해자의 권한을 사용하여 악의적인 요청을 수행할 수 있다.
✔️ CSRF 방지하는 방법
CSRF 토큰 사용: 각 요청에 CSRF 토큰을 포함해 요청의 유효성 검증.
CSRF 토큰: CSRF 토큰은 사용자의 요청이 실제로 사용자의 의도에 따라 생성된 것인지 확인하는 데 사용되는 보안 메커니즘.
SameSite 쿠키 속성 설정 -> Strict 혹은 Lax로 설정되어야 함.
요청의 리퍼러 헤더를 체크해 요청이 원본 사이트에서 발생했는지 확인.
리퍼러 헤더(Referer Header): 웹 요청이 발생한 출처 페이지의 URL을 포함하는 HTTP 헤더. But, 리퍼러 헤더는 항상 신뢰할 수는 없으며, 브라우저가 지원하지 않을 수도 있다.
✅ 프로젝트에서 보안 고려하기
- HTTP Only 쿠키: 이 쿠키는 JavaScript에서 접근할 수 없으며, 오직 HTTP 요청과 같은 프로토콜을 통해서만 서버로 전송된다. 이를 통해 XSS 공격으로부터 보호됨.
- Secure 쿠키: 이 쿠키는 HTTPS 프로토콜을 통해서만 전송되며, 암호화된 통신을 통해 보안을 강화한다. 이를 통해 중간자 공격으로부터 보호됨.
OAuth는 사용자가 다른 웹사이트 또는 애플리케이션의 리소스에 접근할 수 있도록 권한을 부여하는 오픈 표준 프로토콜.
인터넷 사용자들이 비밀번호를 제공하지 않고 다른 웹사이트 상의 자신들의 정보에 대해 웹사이트나 애플리케이션의 접근 권한을 부여할 수 있는 공통적인 수단으로서 사용되는, 접근 위임을 위한 개방형 표준.
출처: https://inpa.tistory.com/entry/WEB-📚-OAuth-20-개념-💯-정리 [Inpa Dev 👨💻:티스토리]
OAuth 프로토콜은 다양한 흐름을 제공하여 클라이언트가 사용자 데이터에 접근하는 권한을 안전하게 제어한다.
OAuth 1.0은 2007년에 처음 발표되었고, OAuth 2.0은 이전 버전의 몇 가지 단점을 보완하고 확장하여 2012년에 발표되었다.
큰 차이점으로는 OAuth 1.0은 요청에 서명된 토큰을 사용하여 요청을 보호했지만,
OAuth 2.0은 액세스 토큰과 리프레시 토큰을 사용하여 요청을 보호한다. 이는 더 간단하고 유연한 인증 방식을 제공한다. 또 OAuth 2.0는 SSL/TLS(HTTPS)를 기본적으로 요구해 보안을 강화한다.
인가 코드 그랜트(Authorization Code Grant): 웹 애플리케이션과 서버 간의 안전한 권한 부여를 위해 사용됨. 클라이언트가 사용자를 인증하고, 인가 코드를 받은 후에 이를 인증 서버에 교환하여 액세스 토큰을 얻는다. 보안 상의 이점이 있어서 주로 사용됨.
암시적 그랜트(Implicit Grant): 브라우저 기반 JavaScript 애플리케이션에서 사용되며, 리다이렉트를 통해 액세스 토큰을 바로 얻는 방식.
암호 그랜트(Resource Owner Password Credentials Grant): 사용자의 암호를 사용하여 직접 액세스 토큰을 얻는 방식. 일반적으로 보안상의 이유로 권장되지는 않는다.
클라이언트 자격 증명 그랜트(Client Credentials Grant): 클라이언트가 자신의 자격 증명을 사용하여 액세스 토큰을 얻는 방식. 보통 시스템 간 통신에서 사용된다.
JWT(Bearer) 그랜트(JSON Web Token Grant): 클라이언트가 JWT를 사용하여 액세스 토큰을 요청하는 방식.
블로그에서 소셜 로그인을 구현하는 다양한 방식을 봤는데 Oauth의 다양한 인가 방식에 따라 달라질 수 있다.
👉 이번 프로젝트에서는 백엔드 분이 소셜로그인은 Oauth2의 인가 코드 그랜트 방식,
자체 토큰 발급은 스프링 시큐리티, JWT를 사용해 구현해 주셨다.
토큰 저장 위치는 보안을 위해 accessToken은 클라이언트의 메모리에, refreshToken은 HTTP Only Cookie(secure)에 저장하기로 했다.
다음에는 프로젝트에서 이를 어떻게 구현했는지 자세한 포스팅으로 돌아오겠다! 😇