배경
- CSRF 토큰, dom 은 뭐고 왜필요할까?
- 둘은 어떤관계를 가지고 있을까?
본문
1. 한 줄 요약
CSRF 토큰은 로그인이나 폼 전송 시 서버가 발급한 보안 코드이고, DOM은 그 토큰이 담긴 HTML 구조 안에서 우리가 그 값을 추출해내는 장소입니다.
2. 🧠 용어 먼저 정리
✅ CSRF 토큰이란?
- CSRF = Cross-Site Request Forgery (사이트 간 요청 위조)
- 사용자가 로그인한 상태를 악용해, 의도치 않은 요청을 자동으로 보내는 공격을 막기 위해 사용됨
- 서버는 폼 안에 무작위 토큰을 삽입해서, 이 토큰이 없거나 틀리면 요청을 거부함
<!-- 예: 로그인 폼 HTML -->
<form method="POST" action="/login">
<input type="text" name="username">
<input type="password" name="password">
<input type="hidden" name="csrf_token" value="abc123xyz"> <!-- ← 이게 CSRF 토큰 -->
</form>
CSRF 토큰은 HTML 안에 숨겨진 input 필드로 들어가며,
서버는 이 값을 확인해 정상 요청인지 판단합니다.
✅ DOM이란?
- DOM (Document Object Model) = 웹페이지의 HTML 구조를 트리 형태로 표현한 것
- 웹페이지의 모든 요소(
div
,form
,input
등)는 DOM의 노드(Node) 로 표현됨 - JavaScript, Selenium, BeautifulSoup 등을 통해 접근하거나 조작할 수 있음
예시 DOM 구조:
<html>
<body>
<form id="login-form">
<input type="text" name="username">
<input type="password" name="password">
<input type="hidden" name="csrf_token" value="abc123xyz"> <!-- ← 여기서 추출 -->
</form>
</body>
</html>
3. 🔗 CSRF 토큰과 DOM의 관계
개념 | 역할 | 관계 |
---|---|---|
CSRF 토큰 | 폼 요청이 안전한지 판단하는 보안 코드 | DOM 안에 숨겨진 필드로 포함됨 |
DOM | 웹페이지의 HTML 요소를 구조적으로 표현 | CSRF 토큰이 들어 있는 위치를 탐색 가능 |
즉, 크롤러 입장에서는 "DOM을 파싱해서 CSRF 토큰을 추출해야" 로그인을 정상적으로 요청할 수 있습니다.
4. 🛠 실전 예시 (requests + BeautifulSoup)
import requests
from bs4 import BeautifulSoup
# 로그인 페이지에 먼저 접속
session = requests.Session()
r = session.get("https://example.com/login")
# DOM 파싱을 통해 CSRF 토큰 추출
soup = BeautifulSoup(r.text, 'html.parser')
csrf_token = soup.find("input", {"name": "csrf_token"})["value"]
# 토큰 포함해서 로그인 요청
session.post("https://example.com/login", data={
"username": "test",
"password": "1234",
"csrf_token": csrf_token
})
5. ❗왜 이걸 모르면 로그인 실패할까?
requests.post()
로 바로 로그인하면 서버는 CSRF 토큰이 없다고 판단하고 거부함- 브라우저(Selenium)는 HTML을 실제 렌더링하고 DOM에서 자동으로 이 값을 읽어 전달하기 때문에 성공
✅ 결론
항목 | 설명 |
---|---|
CSRF 토큰 | 서버가 발급한 1회용 보안 코드 |
DOM | HTML 문서의 구조 표현 (브라우저나 BeautifulSoup이 접근하는 대상) |
관계 | CSRF 토큰은 DOM 내부 <input> 에 숨겨져 있으며, 이를 파싱해 추출해야 로그인 성공 가능 |
'크롤링' 카테고리의 다른 글
로그인시 토큰을 요청하는 이유 (0) | 2025.04.22 |
---|---|
Post 로그인이 안됐던 이유 (1) | 2025.04.22 |
request에서 get, post, put 등의 의미와 사용예시 (0) | 2025.04.22 |
크롤링 시 HEADERS를 활용해 사람인척 하기 (1) | 2025.02.12 |