클라이언트가 요청을 보냈을 때, 그 클라이언트가 누구인지 정확히 알지도 못하는데 아무 정보나 제공하게 되면 그것이 바로 유출이 되는 것 ㅋㅋ
그래서 프론트엔드에서 사용자가 누군지에 대한 정보를 서버에 보내줘야하고, 서버는 그 정보를 바탕으로 사용자에게 맞는 데이터를 제공해야한다.
DRF는 다양한 애플리케이션 요구 사항을 충족하기 위해 여러 가지 인증 방식을 제공한다. 각각의 장단점이 있고 쓰임세도 있지만
이번 포스팅에는 몇몇 DRF 인증 방식에 대해서 가볍게 알아보려고 한다.
Basic Authentication(기본 인증)
은 웹 애플리케이션에서 사용자를 인증하기 위한 간단한 인증 방식 중 하나로, 사용자 이름과 비밀번호를 HTTP 요청 헤더에 인코딩하여 전송하고, 서버에서 해당 정보를 검증하여 사용자를 인증한다.
단점은 계정 정보를 매번 요청에 넣어서 보내기에는 보안에 너무 취약하여 만약 헤커가 HTTP 요청을 가로채면 사용자 개인 정보를 빼갈 수도 있다.
HTTPS 연결로 HTTP 요청을 암호화하여 보안을 높일 수도 있지만 실제 서비스에서는 잘 사용하지 않는 방식이다.
Session Authentication(세션 인증)
은 웹 애플리케이션에서 사용자의 로그인 상태를 유지하고 관리하기 위한 방식으로, 서버 측에서 사용자 정보를 저장하고, 클라이언트는 세션 식별자를 쿠키를 통해 전달하여 세션을 식별한다.
def signin(request): # 로그인 페이지 함수 입니다. if request.method == "GET": return render(request, 'user/signin.html') elif request.method == "POST": username = request.POST['username'] password = request.POST['password'] user = authenticate(request, username=username, password=password) if user is not None: login(request, user) return redirect('/') else: return render(request, 'user/signin.html') else: return HttpResponse("Invalid request method", status=405)
이 코드에서는 세션 ID와 쿠키가 사용되고 있다.
1. 사용자가 로그인을 시도하면 POST 메서드를 통해 사용자가 제출한 아이디(username)와 비밀번호(password)가 서버로 전송된다.
2. 서버는authenticate
함수를 사용하여 사용자의 인증을 시도한다. 만약 사용자가 제공한 아이디와 비밀번호가 유효하면, 세션 및 쿠키를 생성하고 사용자를 로그인 상태로 만든다.
3.signin
함수에서는 사용자의 로그인을 시도했고!! 이 함수와는 별개로 장고 내장 함수인login
함수를 호출하여 사용자를 로그인 상태로 변경하고, 이 과정에서 세션 ID 및 쿠키가 설정된다.
4. 로그인에 성공하면 사용자는 홈페이지(/)로 리디렉션된다. 이때 세션 ID나 쿠키는 브라우저에 저장되며, 사용자가 로그인한 상태를 유지할 수 있도록 한다.
현대 사회에서 세션 방식은 한계가 있다.
이 방식은 쿠키를 매개로 인증하는 방식이다. 세션 ID가 담긴 쿠키는 사용자 정보를 얻기 위한 열쇠라고 생각하면 된다.
'이 쿠키가 담긴 HTTP 요청이 도중에 노출되더라도 노출된 쿠키에 든 세션 ID는 그냥 무의미한 값이다' 라고 생각할 수 있지만 만약 해커가 훔친 세션 ID로 HTTP 요청을 보내면 서버의 세션 저장소에서는 세션 ID만으로 사용자를 식별하기 때문에 사용자를 오인해서 계정 정보가 노출될 수 있다.
이를 해결하는 방법으로는,
HTTPS를 사용해서 HTTP요청을 암호화하여 HTTP 요청이 노출되어도 안의 정보를 읽기 힘들게 하거나 세션에 유효시간을 넣어주는 방법이 있다.
Session
서버 측에서 사용자 정보를 안전하게 관리하고 저장하는 메커니즘으로 클라이언트는 세션 식별자를 쿠키를 통해 받아 저장하고, 서버는 이 세션 식별자를 사용하여 사용자를 식별한다.
Cookie
클라이언트 측에 저장되는 작은 데이터 조각으로, 클라이언트 브라우저에 저장된다. 주로 사용자 식별 및 상태 유지를 위해 사용되며, 세션 식별자를 클라이언트에게 전달할 때 사용된다.
이러한 한계들 때문에 현대의 웹 애플리케이션은 세션 방식보다는 상태를 보존하지 않는 방식(stateless)과 토큰 기반의 인증(Authentication Tokens) 방식을 선호하며, RESTful API와의 호환성을 강조하는 추세가 있다.
특히 모바일 애플리케이션과 다양한 플랫폼 간의 통신을 간소화하고 확장성을 향상시키기 위해 토큰 기반의 인증 방식(JSON Web Tokens, OAuth)이 많이 사용된다.
Token Authentication(토큰 인증)은 웹 애플리케이션 및 API에서 사용자 인증을 관리하기 위한 방법 중 하나이다. Token(토큰)
은 변조할 수 없는 인증 파일로, 사용자가 로그인하면 서버에서 고유한 토큰을 생성하고, 이 토큰을 클라이언트(예: 웹 브라우저 또는 모바일 앱)에게 제공한다.
사용자는 이 토큰을 안전하게 브라우저의 쿠키나 로컬스토리지와 같은 로컬 저장소에 전송하고 저장한다. 쿠키와 마찬가지로 사용자는 새로운 API 요청이 있을 때마다 이 토큰을 서버에 토큰을 함께 전송한다.
서버는 클라이언트로부터 받은 토큰의 서명을 확인하고, 유효한 경우 요청을 승인한다.
비밀 키를 사용하여 서버에서 생성되고
토큰을 받는 동안 서버는 사용자가 누구인지 조회 하지 않고 단순히 토큰의 유효성에 따라 사용자의 요청을 승인한다. 이 말은 즉, 서버는 사용자가 로그인했는지 안했는지 알 수가 없다.
토큰은 사용자가 자격 증명을 보내야 하는 횟수를 줄이고 싶을 때 유용할 수 있다. 서버 간 연결의 경우 자격 증명을 사용하는 것이 어려워지며 토큰이 이 문제를 해결할 수 있다. 또한 토큰을 사용하는 서버는 사용자의 요청을 승인하기 위해 모든 세션 세부 정보를 지속적으로 확인할 필요가 없기 때문에 성능을 향상시킬 수 있다.
특히 JWT(JSON Web Tokens)는 Token Authentication의 한 형태로 사용되며, 토큰에 JSON 형식의 정보를 포함하고 서명을 통해 검증된다.
- 형태
- Key와 Value 쌍으로 데이터를 저장한다.
- 데이터는 문자열 형태로 저장되지만, 서버에서 설정된 추가 속성도 가질 수 있다.
- 각 쿠키는 도메인, 경로, 만료 날짜 등의 속성을 가진다.
- 세션 쿠키와 영구 쿠키로 구분되며, 세션 쿠키는 브라우저를 닫으면 삭제되고, 영구 쿠키는 설정된 만료 날짜까지 유지된다.
- 장점
- 서버 및 클라이언트 간에 데이터를 주고받을 때 자동으로 전송된다.
- 쿠키에는 HttpOnly 및 Secure와 같은 보안 옵션을 적용하여 보안을 강화할 수 있다.
- 단점
- 쿠키에 저장할 수 있는 데이터 용량은 일반적으로 4KB로 제한된다.
- 복잡한 데이터 저장에는 부적합하다.
- 사용하기 좋은 케이스
- 세션 관리 및 사용자 추적에 적합 (ex. 로그인 상태 유지, 세션 식별)
- 광고 타겟팅, 행동 분석, 방문자 통계 등 분석 및 추적 용도로 사용될 수 있다.
- 세션 기간 동안 데이터 공유 또는 다른 페이지 간 정보 전달에 활용된다.
.getItem
: 데이터 수정, 추가 등 데이터에 엑세스하고 값을 가져올 때.setItem
: 읽기 전용.removeItem
: 로그아웃 할 때, 로컬 스토리지의 데이터 삭제데이터의 지속성과 용량 요구 사항을 고려하여 로컬 스토리지 또는 쿠키를 선택한다.
중요한 데이터나 인증 정보를 저장해야 할 경우 보안 고려 사항을 고려하여 적절한 방식을 선택한다.
세션 관리에 쿠키를 사용하고 사용자 설정을 로컬 스토리지에 저장할 수 있는 것 처럼 필요에 따라 두 기술을 혼합해서 사용할 수 있다.
일반적으로 토큰은 클라이언트 측에 사용 용도와 보안 요구 사항에 따라 로컬 스토리지에 저장되거나, 쿠키에 저장되기도 한다.
HttpOnly 쿠키 속성을 사용하면 HTTPS 연결을 통해서만 전송되고 중요한 정보를 Javascript로부터 숨길 수 있기 때문에 쿠키를 사용하는게 좋고,
더 큰 데이터를 저장해야 하거나 JavaScript로 쉽게 액세스해야 하는 경우에는 로컬 스토리지를 사용하는게 좋다.
🥚🐣🐤🐥🐓🐔