Server
from flask import Flask, request, jsonify
import functools
app = Flask(__name__)
API_KEY = create_api_key()
def create_api_key():
"""
API Key 생성: 실행할때마다 값이 달라지니 주의필요
(생성한 API Key는 ".env", ".json", ".yaml", "DB"에 저장해서 관리)
"""
import uuid
return str(uuid.uuid4())
def api_key_required(f):
"""
API 키 인증을 위한 데코레이터
"""
@functools.wraps(f) # 원래 함수의 메타데이터를 유지
def wrapper(*args, **kwargs):
api_key = request.headers.get("Authorization") # 헤더에서 API 키 추출
if api_key != API_KEY:
print(f"{api_key} != {API_KEY} -> {api_key != API_KEY}")
return jsonify({"message": "Unauthorized"}), 401
return f(*args, **kwargs)
return wrapper
@app.route('/get_api_key', methods=['POST'])
def get_api_key():
if request.headers.get("Authorization") == 'api_key request':
return jsonify({"Authorization": API_KEY})
else:
return jsonify({"message": "Unauthorized"}), 401
@app.route('/kmo_test', methods=['POST'])
@api_key_required # API 키 인증을 통과해야 접근 가능
def protected():
# json_data = request.get_json()
return jsonify({"message": "You have access to this protected resource."})
if __name__ == '__main__':
app.run(host='0.0.0.0', port=88)
"""
[RESULT]
* Serving Flask app '__main__'
* Debug mode: off
2025-02-11 20:06:43,700 INFO WARNING: This is a development server. Do not use it in a production deployment. Use a production WSGI server instead.
* Running on all addresses (0.0.0.0)
* Running on http://127.0.0.1:88
* Running on http://xxx.xxx.xxx.xxx:88
2025-02-11 20:06:43,700 INFO Press CTRL+C to quit
2025-02-11 20:06:51,323 INFO 127.0.0.1 - - [11/Feb/2025 20:06:51] "POST /get_api_key HTTP/1.1" 200 -
2025-02-11 20:06:53,371 INFO 127.0.0.1 - - [11/Feb/2025 20:06:53] "POST /kmo_test HTTP/1.1" 200 -
"""
Client
import requests
import logging
import logging.basicConfig as Config
config(
#filename='application.log',
level=logging.DEBUG,
format='%(asctime)s:%(levelname)s:%(message)s'
)
def server_post(url, data=None, json=None, **kwgrs):
response = requests.post(url=url, data=data, json=json, **kwgrs)
if response.status_code == 200:
logging.info(f"Success, {response.json()}")
else:
logging.error(f"Error, {response.status_code}")
response = 'Error'
return response
def get_headers():
result = server_post(url="http://localhost:88/get_api_key", headers={"Authorization": "api_key request"})
if result != 'Error':
headers = result.json() # 서버에서 설정한 API 키
return headers
if __name__ == '__main__':
headers = get_headers()
logging.info(f"headers: {headers}")
logging.info('')
result = server_post(url="http://localhost:88/kmo_test", headers=headers)
logging.info(f"result: {result.json()}")
"""
[RESULT]
2025-02-11 20:06:49,273 DEBUG Starting new HTTP connection (1): localhost:88
2025-02-11 20:06:51,325 DEBUG http://localhost:88 "POST /get_api_key HTTP/1.1" 200 55
2025-02-11 20:06:51,325 INFO Success, server_post()
2025-02-11 20:06:51,326 INFO headers: {'Authorization': 'cd20432b-e5d1-47c5-b079-c09da77e72a9'}
2025-02-11 20:06:51,326 INFO
2025-02-11 20:06:51,327 DEBUG Starting new HTTP connection (1): localhost:88
2025-02-11 20:06:53,373 DEBUG http://localhost:88 "POST /kmo_test HTTP/1.1" 200 58
2025-02-11 20:06:53,373 INFO Success, server_post()
2025-02-11 20:06:53,374 INFO result: {'message': 'You have access to this protected resource.'}
"""
추가해야할 부분
이대로 사용해도 보안장치가 생겨서 나쁘지 않으나, api-key를 받아올 때나, 확인할 때 키 값을 암호화해서 주고 받으면 취약점을 보완할 수 있을 것으로 보여짐.
암/복호화 방식에는 AES, DES, RSA 등이 있으니 마음에 드는 것을 선택해서 사용하면 됨.
'기타 (Other)' 카테고리의 다른 글
[python] PC 최적화 모델 (0) | 2025.02.11 |
---|---|
[python] PDF 텍스트 추출해서 TXT 파일로 만들기 (0) | 2025.02.11 |
아파치 카프카 (0) | 2025.01.21 |
[python] pandas (4) | 2025.01.09 |
[python] decorator 예제 (0) | 2024.12.07 |