Chapter 5-2 Flask Authentication / Flask-JWT-Extended

2025. 4. 23. 10:17·Flask

📌 개념 정리

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
'Flask' 카테고리의 다른 글
  • Chapter 5-4 Flask로 만드는 인스타그램 REST API
  • Chapter 5-3 Flask와 Jinja를 활용한 사용자 관리 웹 애플리케이션
  • Chapter 5-1 Flask Authentication / Flask-login
  • Chapter 4-8(1) Flask 애플리케이션에서 HTTP 기본 인증 사용
Chansman
Chansman
안녕하세요! 코딩을 시작한 지 얼마 되지 않은 초보 개발자 찬스맨입니다. 이 블로그는 제 학습 기록을 남기고, 다양한 코딩 실습을 통해 성장하는 과정을 공유하려고 합니다. 초보자의 눈높이에 맞춘 실습과 팁, 그리고 개발하면서 겪은 어려움과 해결 과정을 솔직하게 풀어내려 합니다. 함께 성장하는 개발자 커뮤니티가 되기를 바랍니다.
  • Chansman
    찬스맨의 프로그래밍 스토리
    Chansman
  • 전체
    오늘
    어제
    • 분류 전체보기 (657) N
      • Python (32)
      • 프로젝트 (43)
      • 과제 (25)
      • Database (40)
      • 멘토링 (11) N
      • 특강 (34) N
      • 기술블로그 (36) N
      • 기술블로그-Fastapi편 (20) N
      • 기술블로그-Django편 (152) N
      • 기술블로그-Flask편 (35)
      • AI 분석 (4)
      • HTML & CSS (31)
      • JavaScript (17)
      • AWS_Cloud (21)
      • 웹스크래핑과 데이터 수집 (14)
      • Flask (42)
      • Django (72)
      • Fastapi (1) N
  • 블로그 메뉴

    • 홈
    • 태그
    • 방명록
  • 링크

  • 공지사항

  • 인기 글

  • 태그

  • 최근 댓글

  • 최근 글

  • hELLO· Designed By정상우.v4.10.3
Chansman
Chapter 5-2 Flask Authentication / Flask-JWT-Extended
상단으로

티스토리툴바