티스토리 뷰
1. OAuth의 작동
1) 인증(Authentication) : 사용자가 신뢰할 수 있는 인증 제공자(google, naver, kakao 등)를 통해 인증
2) 권한 부여(Authorization) : 사용자가 특정 리소스(예: 이메일, 사진 등)에 대한 엑세스를 승인
3) 엑세스 토큰 발급 : 인증 서버가 발급하는 짧은 수명의 토큰으로, 클라이언트가 API에 요청을 보낼 때 사용
2. 엑세스 토큰(Access Token)
- 사용자를 대신하여 보호된 리소스에 액세스하는데 필요한 키
3. 토큰 관리 원칙
- 짧은 유효기간 : 토큰은 만료 시간이 짧아야 하며, 장기 토큰을 피한다
- 리프레시 토큰 사용: 만료된 액세스 토큰을 갱신하기 위해 리프레시 토큰을 사용
- JWT(Json Web Token) : 서명된 형태로 데이터 페이로드와 함께 제공되며, 추가적인 인증 서버 호출 없이 검증 가능
- JWT의 만료 시간을 짧게 설정하여 보안성을 높이지만, 매번 사용자에게 다시 로그인하게 하면 불편해 리프레시 토큰을 서버에 별도로 저장해 엑세스 토큰 갱신 요청시 추가 검증 과정을 거쳐 사용하기도함
* JWT 구조
1) Header : 토큰의 타입(JWT)과 서명에 사용된 알고리즘 정보를 포함
2) Payload: 토큰에 포함된 클레임 정보(사용자 ID, 역할, 토큰 만료 시간 등)
3) Signature: Header와 Payload를 비밀 키를 사용해 서명하여 생성. 토큰의 무결성을 검증
* JWT 특징
- 토큰에 필요한 모든 정보가 포함되어 있으므로 서버가 상태 정보를 저장할 필요가 없음
- 클라이언트에서 제공된 JWT가 조작되지 않았음을 검증 간으
- 일반적으로 JWT는 짧은 유효기간을 가지며, 만료 후 갱신 필요
* JWT 사용 예시
- 클라이언트가 서버에 로그인 요청> 서버가 사용자 정보를 검증한 후 JWT를 생성해 반환> 클라이언트는 이JWT를 저장(Local Storage 또는 HttpOnly 쿠키)하고, 요청마다 Authorization: Bearer <JWT> 헤더에 포함하여 보냄
4. 쿠키와 보안 설정
- Secure: HTTPS 연결에서만 쿠키가 전송되도록 설정
- HttpOnly: JavaScript로 쿠키에 접근하지 못하도록 설정하여 XSS 공격을 방지
- SameSite: CSRF(Cross-Stie Request Forgery) 공격을 방지하기 위해 Strict 또는 Lax로 설정
- Token Storage: 엑세스 토큰은 로컬 스토리지 대신 HttpOnly 쿠키에 저장하여 안전하게 관리
*HTTPOnly 쿠키와 Token Storage 비교
항목 | HttpOnly 쿠키 | Token Storage |
보안성 | XSS에 강함 (JavaScript 접근 불가) | XSS에 취약 (JavaScript 접근 가능) |
CSRF 취약성 | CSRF에 취약(SameSite 속성으로 방지 가능) | CSRF에 강함(자동 전송 없음) |
편의성 | 자동으로 요청에 포함 | 수동으로 헤더 추가 필요 |
브라우저 외 환경 | 지원이 제한적(웹브라우저 중심) | RESTful API호출에 적합 |
5. 미들웨어
- 요청이 처리되는 동안 인증 및 권한 부여 논리를 삽입할 수 있는 계층
- 미들웨어 사용 패턴
1) 엑세스 토큰 검증
- 요청 헤더의 Authorization: Bearer <token>을 읽음
- 토큰 유효성을 확인하고, 유효하지 않으면 401 응답
2) 쿠키에서 토큰 추출
- 쿠키에 저장된 엑세스 토큰을 읽고 디코딩
- 사용자 권한을 확인
3) 로그인 상태 유지
- 리프레시 토큰을 사용해 엑세스 토큰을 갱신
- 토큰 갱신 로직을 미들웨어에 포함하여 사용자 경험을 개선
<구현 예시>
from fastapi import FastAPI, Request, HTTPException, Depends
from fastapi.middleware.cors import CORSMiddleware
from jose import JWTError, jwt
app = FastAPI()
# JWT 토큰 검증을 위한 키 및 알고리즘
SECRET_KEY = "your-secret-key"
ALGORITHM = "HS256"
# 미들웨어를 통한 요청 처리
@app.middleware("http")
async def validate_token(request: Request, call_next):
token = request.cookies.get("access_token") # 쿠키에서 토큰 추출
if token:
try:
payload = jwt.decode(token, SECRET_KEY, algorithms=[ALGORITHM])
request.state.user = payload # 유효한 경우 사용자 정보 저장
except JWTError:
raise HTTPException(status_code=401, detail="Invalid token")
return await call_next(request)
@app.get("/secure-endpoint")
async def secure_endpoint(request: Request):
if not request.state.user:
raise HTTPException(status_code=401, detail="Unauthorized")
return {"message": "Welcome, authorized user!"}
6. 보안 최적화
- HTTPS 적용: 모든 통신에 SSL/TLS를 사용해 데이터 암호화
- CSRF 방지: 쿠키 기반 인증을 사용하는 경우 CSRF 토큰 사용
- IP 및 디바이스 제한: 인증 시 IP 또는 디바이스 기반 필터링 추가
- 토큰 블랙리스트: 만료되거나 강제로 무효화된 토큰 처리
'AI > AI 서비스 개발' 카테고리의 다른 글
[AI 서비스 개발] 멀티 에이전트, 에이전트 라우터 (0) | 2025.01.16 |
---|---|
[AI 서비스 개발] 구글 로그인(OAuth) (0) | 2025.01.15 |
[AI 서비스 개발] 애자일(Agile), 스프린트, 에픽, 사용자 스토리, TASK (0) | 2025.01.11 |
[AI 서비스 개발] 라우터와 엔드포인트 (0) | 2025.01.08 |
[AI 서비스 개발] Git 명령어 (1) | 2025.01.04 |
- Total
- Today
- Yesterday
- opic
- 오픽
- 갓생
- 빅데이터 분석기사
- 고득점 Kit
- 실기
- 티스토리챌린지
- 운동
- 기초
- IH
- 스크랩
- 루틴
- 다이어트
- 아침
- llm
- Python
- SQL
- 30분
- C언어
- ChatGPT
- 뉴스
- 프로그래머스
- 아침운동
- 영어회화
- Ai
- 미라클모닝
- 오블완
- 습관
- 줄넘기
- 경제
일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | 4 | |||
5 | 6 | 7 | 8 | 9 | 10 | 11 |
12 | 13 | 14 | 15 | 16 | 17 | 18 |
19 | 20 | 21 | 22 | 23 | 24 | 25 |
26 | 27 | 28 | 29 | 30 | 31 |