데코레이터란
What is a Decorator
데코레이터란 함수에 반복적인 기능과 역할을 할 수 있도록 만들어주는 기능이다. 함수 내부의 로직을 수정하지않고, 기능을 추가하거나 수정 하고싶을 때 사용한다.
일반적으로는 함수의 전처리/후처리 등에대해 필요가 있을 때 사용한다.
A decorator is a feature that allows you to add repetitive functionality and roles to functions. It is used when you want to add or modify functionality without changing the internal logic of a function.
It is generally used when there is a need for pre-processing or post-processing of functions.
데코레이터 사용하기
Using Decorators
물론 여러가지 미리 작성된 기능들이 있지만, 인증과 관련된 부분을 커스터마이징 해 보려고 한다.
(인증은 장고의 @login_required() 와 같은 데코레이터들이 이미 있다)
Of course, there are various pre-written features available, but I'm going to try customizing the authentication-related part.
(For authentication, decorators like Django's @login_required() already exist)
데코레이터 선언
Declaring a Decorator
from flask import request
from functools import wraps
def api_decorator():
def api_auth_decorator(f):
@wraps(f)
def _api_auth_decorator(*args, **kwargs):
result = f(*args, **kwargs)
token = request.headers.get("Authorization")
if token is None:
return {"message": "허가되지 않은 접근입니다.", }, 401
if datetime.datetime.now() >= time_checker(token)
# time_checker는 현재 token의 만료기간을 체크하는 임의의 함수입니다
return {"message": "토큰이 올바르지 않습니다.", }, 401
return result
return _api_auth_decorator
return api_auth_decorator
- 우선, wraps로 데코레이터를 만들어 줄 함수를 정의한다
- 함수를 인자로 받아서, 해당하는 함수가 실행 되기 전에 미리 실행한다
- 인자로 받은 *args, **kwargs 들을 가져와서 request되는 정보들을 뽑아본다.
- (예제로는) header 안에 있는 "Authorization" 을 뽑아 token을 체크한다
- First, define a function that will create a decorator using wraps
- Receive a function as an argument and execute it before the corresponding function runs
- Retrieve the *args and **kwargs received as arguments to extract the request information
- (In this example) Extract the "Authorization" from the header to check the token
데코레이터 적용
Applying the Decorator
로그인이 필요한 코멘트를 작성하는 API를 간단히 예시로 들어보았다
Here is a simple example of an API for writing comments that requires login
@app.route("/post/comment", methods=["POST"])
@api_decorator()
def post_comment():
params = json.loads(request.get_data())
context = params.get("context",None)
user_id = params.get("userId",None)
post_id = params.get("postId",None)
CommentModel.create(
context = context,
user_id = user_id,
post_id = post_id,
)
return {"message":"코멘트 작성이 완료되었습니다"}
위에 작성했던 api_dcorator() 를 사용하지 않았다면, 해당하는 router마다 로그인이 되어있는지, 토큰을 체크 해 주어야 하는지에대해서 매번 서비스로직을 넣어 확인 해야 한다
If you didn't use the api_decorator() written above, you would have to add service logic to check whether the user is logged in and whether to verify the token for each corresponding router every time
비슷한 기능을 하는 함수들
Functions with Similar Functionality
Flask는 프레임워크이다. 그래서 우리가 만들 데코레이터들과 비슷한 기능을 이미 제공 해 주고 있다.
Flask is a framework. Therefore, it already provides features similar to the decorators we will create.
before_first_request
- 플라스크 서버가 실행되고 가장 첫 요청 전에 사용되는 로직
- Logic that is used before the very first request after the Flask server starts
from flask import Flask, jsonify
app = Flask(__name__)
@app.route("/")
def before_first_request():
log.info("플라스크가 실행된 후, 가장 첫 request 요청에서만 사용")
return jsonify({"msg":"before_first_request"})
before_request
- 플라스크 서버가 실행되고 매 request전에 사용
- Used before every request after the Flask server starts
from flask import Flask, jsonify
app = Flask(__name__)
@app.route("/")
def before_request():
log.info("플라스크가 실행된 후, request 요청 전에 사용")
return jsonify({"msg":"before_request"})
after_request
- 플라스크 서버가 실행되고 매 request 이후에 사용
- Used after every request once the Flask server starts
from flask import Flask, jsonify
app = Flask(__name__)
@app.route("/")
def after_request():
log.info("플라스크가 실행된 후, request 이후에 사용")
return jsonify({"msg":"after_request"})
이외에도 teardown_request, teardown_appcontext 등이 존재한다!
Besides these, there are also teardown_request, teardown_appcontext, and more!