[python] Flask-RESTful에서 JWT를 활용한 인증 방법
목차
JWT란 무엇인가요?
JWT는 JSON Web Token의 약자로, 웹 애플리케이션에서 토큰 기반 인증을 구현하기 위해 사용됩니다.
JWT는 세 가지 부분으로 구성되어 있습니다:
- 헤더(Header): 토큰의 유형(JWT)과 해싱 알고리즘 정보가 포함되어 있습니다.
- 페이로드(Payload): 토큰에 첨부할 클레임(claim) 정보가 담겨 있습니다. 클레임은 토큰에 담고 싶은 정보를 의미하며, 이름과 값의 쌍으로 이루어져 있습니다.
- 서명(Signature): 헤더의 인코딩 값, 페이로드의 인코딩 값, 비밀키를 사용하여 생성됩니다. 이 서명은 토큰의 유효성을 검증하는데 사용됩니다.
Flask-RESTful에서 JWT를 사용하기 위한 설정
from flask import Flask
from flask_jwt_extended import JWTManager
app = Flask(__name__)
app.config['SECRET_KEY'] = 'your-secret-key'
jwt = JWTManager(app)
SECRET_KEY
는 토큰 서명에 사용되는 키로, 반드시 비밀로 유지되어야 합니다.JWTManager
객체를 생성하여 Flask 앱과 연결합니다.
인증 과정 구현
from flask import request
from flask_jwt_extended import create_access_token, jwt_required, get_jwt_identity
# 로그인 요청 처리
@app.route('/login', methods=['POST'])
def login():
username = request.json.get('username')
password = request.json.get('password')
# username과 password를 검증하는 로직을 구현합니다.
# 검증에 성공한 경우, 엑세스 토큰을 생성하여 반환합니다.
access_token = create_access_token(identity=username)
return {'access_token': access_token}, 200
# 로그인 후 보호되는 API 예시
@app.route('/protected', methods=['GET'])
@jwt_required()
def protected():
current_user = get_jwt_identity()
return {'username': current_user}, 200
/login
경로에 POST 요청이 들어오면, 받은 사용자 이름과 비밀번호를 검증하는 로직을 구현합니다. 성공한 경우 엑세스 토큰을 생성하여 반환합니다./protected
경로에 GET 요청이 들어오면,jwt_required
데코레이터를 이용하여 토큰의 유효성을 검증합니다. 검증이 성공하면 현재 사용자의 정보를 반환합니다.
토큰 검증과 보안 강화
Flask-RESTful에서는 JWT의 토큰 검증을 처리해주는 데코레이터 @jwt_required
를 제공합니다. 이를 이용하여 API 엔드포인트에 쉽게 토큰 유효성 검사를 추가할 수 있습니다.
추가적으로, decode_token
메서드를 사용하여 토큰의 유효성을 검사하고, 토큰의 데이터를 확인할 수도 있습니다.
from flask_jwt_extended import decode_token, verify_jwt_in_request
@jwt_required(optional=True) # 접근 가능한 기능이므로 optional 옵션 사용
def protected():
verify_jwt_in_request(optional=True)
current_user = get_jwt_identity()
access_token = request.headers.get('Authorization', None)
# 토큰 유효성을 검증하고, 필요한 추가적인 체크 로직을 구현합니다.
if access_token:
decoded_token = decode_token(access_token)
# 토큰의 만료 시간 등 추가적인 정보를 확인합니다.
return {'username': current_user}, 200