📌 개념 정리
Flask-JWT-Extended는 Flask에서 JWT(JSON Web Token)를 보다 쉽게 사용할 수 있도록 도와주는 확장 라이브러리입니다. JWT는 사용자의 인증 상태를 안전하게 클라이언트와 서버 간에 전달하는 방식으로, 주로 로그인 인증과 권한 관리에 활용됩니다.
✅ 주요 기능:
- 액세스 토큰 / 리프레시 토큰 생성
- 토큰 블랙리스트 관리
- 사용자 정보(claims) 삽입
- 만료, 폐기된 토큰에 대한 콜백 처리 등
설치 방법:
pip install Flask-JWT-Extended
🚦 동작 원리 및 구조
JWT 인증 시스템은 다음과 같은 구성으로 이루어져 있습니다:
구성요소 설명
Flask 앱 (app.py) | JWT 설정, 블루프린트 등록 및 Flask 앱 구동 |
JWT 설정 (jwt_utils.py) | 비밀키, 만료 시간, 콜백, 블랙리스트 관리 |
라우트 (routes/user.py) | 사용자 로그인, 로그아웃, 보호된 API 처리 |
모델 (models/user.py) | 사용자 정보 관리 모델 |
HTML 템플릿 | 로그인 및 보호된 페이지를 위한 프론트엔드 구성 |
💻 코드 예시 및 흐름 분석
1. Flask 앱 설정 (app.py)
from flask import Flask, render_template
from routes.user import user_bp
from jwt_utils import configure_jwt
app = Flask(__name__)
configure_jwt(app)
app.register_blueprint(user_bp, url_prefix='/user')
@app.route('/')
def index():
return render_template('index.html')
if __name__ == '__main__':
app.run(debug=True)
2. JWT 설정 (jwt_utils.py)
from flask_jwt_extended import JWTManager
from blocklist import BLOCKLIST
from flask import jsonify
jwt = JWTManager()
def configure_jwt(app):
app.config["JWT_SECRET_KEY"] = "your-secure-key"
app.config["JWT_ACCESS_TOKEN_EXPIRES"] = 3600 # 1시간 설정
jwt.init_app(app)
@jwt.additional_claims_loader
def add_claims_to_jwt(identity):
return {"is_admin": identity == 1}
@jwt.token_in_blocklist_loader
def check_if_token_in_blocklist(jwt_header, jwt_payload):
return jwt_payload["jti"] in BLOCKLIST
@jwt.expired_token_loader
def expired_token_callback(jwt_header, jwt_payload):
return jsonify({"msg": "Token expired"}), 401
@jwt.invalid_token_loader
def invalid_token_callback(error):
return jsonify({"msg": "Invalid token"}), 401
@jwt.unauthorized_loader
def missing_token_callback(error):
return jsonify({"msg": "Access token required"}), 401
@jwt.revoked_token_loader
def revoked_token_callback(jwt_header, jwt_payload):
return jsonify({"msg": "Token revoked"}), 401
3. 사용자 라우트 (routes/user.py)
from flask import Blueprint, jsonify, request, render_template
from flask_jwt_extended import create_access_token, create_refresh_token, jwt_required, get_jwt_identity, get_jwt
from models.user import User
from blocklist import add_to_blocklist
user_bp = Blueprint('user', __name__)
users = {'user1': User('1', 'user1', 'pw123')}
@user_bp.route('/login', methods=['POST'])
def login():
data = request.get_json()
user = users.get(data['username'])
if user and user.password == data['password']:
access_token = create_access_token(identity=user.username)
refresh_token = create_refresh_token(identity=user.username)
return jsonify(access_token=access_token, refresh_token=refresh_token)
return jsonify({"msg": "Invalid credentials"}), 401
@user_bp.route('/protected')
@jwt_required()
def protected():
return jsonify(logged_in_as=get_jwt_identity())
@user_bp.route('/logout', methods=['POST'])
@jwt_required()
def logout():
jti = get_jwt()["jti"]
add_to_blocklist(jti)
return jsonify({"msg": "Logged out successfully"})
🧪 실전 사례
- 로그인: POST /user/login → JWT 발급
- 보호된 API 접근: GET /user/protected → JWT 확인
- 로그아웃: POST /user/logout → 토큰 블랙리스트 처리
🧠 고급 팁 or 자주 하는 실수 ✅ 토큰 저장 위치는 보안성에 따라 httpOnly 쿠키를 고려 ✅ JWT_SECRET_KEY는 매우 중요한 보안 키로서 항상 비밀 유지 ✅ 블랙리스트를 꼭 설정해 로그아웃 처리를 명확히 해야 함
✅ 마무리 요약 및 복습 포인트
- Flask-JWT-Extended는 Flask 앱에서 JWT 인증을 간편하게 해준다.
- 주요 데코레이터 활용으로 보호된 API를 구성할 수 있다.
🔑 JWTManager 주요 데코레이터 완벽 정리
JWT를 Flask 애플리케이션에서 사용할 때 가장 유용한 데코레이터를 쉽게 이해할 수 있도록 정리했습니다. 각 데코레이터의 사용 예시와 의미를 함께 살펴보세요.
1️⃣ @jwt_required()
정의 및 역할:
- 해당 엔드포인트에 접근하려면 반드시 유효한 JWT가 필요합니다.
- 클라이언트는 요청 시 JWT를 제공해야 합니다.
사용 예시:
from flask_jwt_extended import jwt_required
@jwt_required()
def protected_route():
# JWT가 유효할 때만 실행되는 로직
return "Protected content"
2️⃣ @jwt_optional()
정의 및 역할:
- JWT는 선택적으로 제공할 수 있습니다.
- JWT가 있으면 유효성을 검사하고 없으면 바로 진행됩니다.
사용 예시:
from flask_jwt_extended import jwt_optional, get_jwt_identity
@jwt_optional()
def optional_route():
current_user = get_jwt_identity()
if current_user:
return f"Hello, {current_user}!"
return "Hello, Guest!"
3️⃣ @fresh_jwt_required()
정의 및 역할:
- 반드시 fresh(신규 발급)한 JWT가 필요합니다.
- 로그인 직후 발급된 JWT만 사용 가능합니다.
사용 예시:
from flask_jwt_extended import fresh_jwt_required
@fresh_jwt_required()
def fresh_route():
# 반드시 fresh한 JWT로만 접근 가능
return "Fresh JWT required content"
🔸 추가 옵션:
- @jwt_required(optional=True)
- @jwt_required(fresh=True, optional=True)
4️⃣ @jwt_refresh_token_required()
정의 및 역할:
- 리프레시 토큰(refresh token)이 필요합니다.
- 액세스 토큰 갱신 시 주로 사용됩니다.
사용 예시:
from flask_jwt_extended import jwt_refresh_token_required, create_access_token, get_jwt_identity
@jwt_refresh_token_required()
def refresh_route():
current_user = get_jwt_identity()
new_token = create_access_token(identity=current_user, fresh=False)
return {"access_token": new_token}
✅ 마무리 요약
데코레이터 필수 여부 사용 목적
@jwt_required() | ✅ 필수 | JWT 필수 제공 |
@jwt_optional() | ❌ 선택 | JWT 선택적 제공 |
@fresh_jwt_required() | ✅ 필수 | 신규 JWT 제공 |
@jwt_refresh_token_required() | ✅ 필수 | 리프레시 토큰 제공 |
'Flask' 카테고리의 다른 글
Chapter 5-4 Flask로 만드는 인스타그램 REST API (0) | 2025.04.23 |
---|---|
Chapter 5-3 Flask와 Jinja를 활용한 사용자 관리 웹 애플리케이션 (0) | 2025.04.23 |
Chapter 5-1 Flask Authentication / Flask-login (0) | 2025.04.22 |
Chapter 4-8(1) Flask 애플리케이션에서 HTTP 기본 인증 사용 (0) | 2025.04.22 |
Chapter 4-7(1) 로그인, 세션 관리 및 보안 페이지 Authentication/ Session (0) | 2025.04.22 |