[BACK-006][기초] 로그인 세션과 토큰 흐름 이해하기 > IT 기술 공유

본문 바로가기
사이트 내 전체검색

IT 기술 공유

[BACK-006][기초] 로그인 세션과 토큰 흐름 이해하기

페이지 정보

profile_image
작성자 기술팀장
댓글 0건 조회 169회 작성일 26-09-01 20:35

본문

[이번 수업]

로그인 성공 뒤 서버가 세션을 만들고, 브라우저나 API가 토큰을 보내며, 서버가 이를 검증·만료·폐기하는 흐름을 배웁니다.

[선수지식]

BACK-001·002의 HTTP 요청·헤더와 BACK-005의 입력 검증을 알면 됩니다. SEC-003의 인증과 인가 구분도 도움이 됩니다.

[학습목표]

1. 세션과 토큰의 역할을 구분한다.
2. 로그인부터 로그아웃까지 생명주기를 설명한다.
3. 추측하기 어려운 세션 ID를 로컬에서 발급·검증한다.

[핵심개념]

로그인은 비밀번호·패스키 같은 인증자를 확인해 사용자를 식별하는 단계입니다. 성공 뒤 매 요청마다 비밀번호를 다시 보내지 않고, 서버가 짧은 임의값인 세션 ID를 발급합니다. 서버 저장소에는 세션 ID와 사용자 ID·만료 시각을 연결합니다. 브라우저가 가진 값만으로 사용자를 믿지 말고 서버가 존재·만료·폐기 여부를 확인해야 합니다.

쿠키 방식은 응답의 `Set-Cookie`로 세션 ID를 저장하고 다음 요청의 `Cookie`로 돌려보냅니다. 브라우저 로그인이라면 보통 `Secure; HttpOnly; SameSite=Lax; Path=/` 같은 속성을 검토합니다. 쿠키에는 비밀번호나 개인정보를 넣지 않습니다.

토큰은 자격을 나타내는 문자열의 넓은 이름입니다. OAuth Bearer 접근 토큰은 API 요청의 `Authorization: Bearer 값` 헤더로 보낼 수 있습니다. 가진 사람이 사용할 수 있으므로 URL, 화면, 로그에 남기지 않습니다.

흐름은 ① TLS에서 로그인 검증 ② 성공 직후 새 ID 발급 ③ 매 요청에서 세션과 만료 확인 ④ 별도 인가 검사 ⑤ 로그아웃·만료 시 서버 저장소에서 폐기와 쿠키 삭제 순서입니다. 로그인이나 권한 변경 뒤 ID를 새로 발급하면 세션 고정 위험을 줄일 수 있습니다.

[따라하기]

다음을 `session_lab.py`로 저장합니다. 인증은 이미 성공했다고 가정하며 실제 비밀번호나 네트워크를 다루지 않습니다.

```python
import hashlib
import secrets
import time

TTL = 60
sessions = {}

def key(token):
    return hashlib.sha256(token.encode()).hexdigest()

def login(user_id):
    token = secrets.token_urlsafe(32)
    sessions[key(token)] = {
        "user_id": user_id,
        "expires_at": time.time() + TTL,
    }
    return token

def current_user(token):
    session = sessions.get(key(token))
    if not session or session["expires_at"] <= time.time():
        sessions.pop(key(token), None)
        return None
    return session["user_id"]

def logout(token):
    sessions.pop(key(token), None)

token = login("user-1")
print("요청:", current_user(token))
logout(token)
print("로그아웃:", current_user(token))
```

macOS/Linux는 `python3 session_lab.py`, Windows PowerShell은 `python session_lab.py`로 실행합니다. 예상 결과는 `요청: user-1`, `로그아웃: None`입니다. 토큰 자체는 출력하지 않습니다.

[흔한 실수]

- 쿠키의 사용자 ID를 검증 없이 신뢰합니다.
- 세션 ID나 접근 토큰을 URL·로그에 남깁니다.
- 만료·로그아웃·강제 폐기 경로를 만들지 않습니다.
- 로그인 전후에 같은 세션 ID를 계속 씁니다.
- `SameSite`만 설정하고 CSRF 방어와 인가를 생략합니다.

[보안 주의]

운영에서는 직접 만든 세션 코드보다 최신 프레임워크 기능을 사용하세요. 모든 인증 정보는 TLS로 전송하고, 쿠키에 Secure·HttpOnly·적절한 SameSite를 설정합니다. 쿠키 기반 변경 요청에는 CSRF 방어를 두고 로그인 시도 횟수 제한과 일반화된 실패 메시지를 적용합니다. 비밀번호는 검증된 비밀번호 해시 기능으로 저장하며 토큰 원문을 로그에 남기지 않습니다.

[직접 해볼 과제]

1. `TTL = 0`으로 바꾸어 즉시 만료되어 `None`이 나오는지 확인하세요.
2. 새 토큰을 발급할 때 이전 토큰을 폐기하고 두 결과를 `assert`로 검사하세요.

[확인문제]

1. 세션 ID와 사용자 정보를 분리해 저장하는 이유는 무엇인가요?
2. Bearer 토큰을 URL에 넣으면 안 되는 이유는 무엇인가요?
3. 로그아웃할 때 쿠키 삭제와 서버 세션 폐기를 함께 해야 하는 이유는 무엇인가요?

[다음 학습]

BACK-007에서는 데이터베이스 연결과 트랜잭션으로 여러 변경을 안전하게 묶습니다.

[공식 참고 자료]

- HTTP 쿠키 표준 RFC 6265: https://www.rfc-editor.org/rfc/rfc6265.html
- Bearer 토큰 사용 RFC 6750: https://www.rfc-editor.org/rfc/rfc6750.html
- OWASP 세션 관리 지침: https://cheatsheetseries.owasp.org/cheatsheets/Session_Management_Cheat_Sheet.html
- Python secrets 문서: https://docs.python.org/3/library/secrets.html
- OWASP 비밀번호 저장 지침: https://cheatsheetseries.owasp.org/cheatsheets/Password_Storage_Cheat_Sheet.html

댓글목록

등록된 댓글이 없습니다.

회원로그인

회원가입

사이트 정보

회사명 : 회사명 / 대표 : 대표자명
주소 : OO도 OO시 OO구 OO동 123-45
사업자 등록번호 : 123-45-67890
전화 : 02-123-4567 팩스 : 02-123-4568
통신판매업신고번호 : 제 OO구 - 123호
개인정보관리책임자 : 정보책임자명

접속자집계

오늘
3,903
어제
6,862
최대
16,772
전체
769,854
Copyright © 소유하신 도메인. All rights reserved.