@login_required 애너테이션 순서

@bp.route
@login_required
def func():

은 잘 실행되는데

@login_required
@bp.route
def func():

로 순서를 바꾸면 @login_required가 기능을 못하네요


애너테이션 순서가 중요한가요?

2323 512

2021년 1월 21일 2:04 오전

목록으로
2개의 답변이 있습니다. 1 / 1 Page

decorator annotation 표현은 아래와 같이 바꿀 수 있습니다

@bp.route()
@login_required
def func():
ㅤㅤ‌pass

->

def func()
ㅤㅤpass

func = bp.route()(login_required(func))

Flask의 Blueprint.route method가 어떻게 이루어져있는지 내부적으로 살펴본다면 정확하지는 않지만 대략 아래와 같습니다.

class Blueprint(...):

ㅤㅤ(...)
ㅤㅤdef route(self, url_rule, (...)):
ㅤㅤㅤㅤdef bp_register_decorator(func):
ㅤㅤㅤㅤㅤㅤself.add_url_rule(func, (...))
ㅤㅤㅤㅤㅤㅤreturn func
ㅤㅤㅤㅤreturn bp_register_decorator

따라서 bp.route()는 blueprint에 함수를 등록하는 데코레이터를 반환합니다. 즉, bp.route() 는 인자로 들어온 함수를 blueprint에 등록한 후 함수 그 자체를 return 값으로 반환합니다.
login_required 함수는 인자로 들어온 함수를 기반으로 하여 새로운 함수를 반환합니다.
따라서 실제 func의 값은 login_required(func)가 되고, blueprint에도 동일한 함수가 등록됩니다.

만약 위에서 decorator의 순서를 바꾼다면, 아래와 같은 표현과 같아집니다.

func = login_required(bp.route()(func))

이 경우에는 실제 func의 값은 login_required(func) 로 동일하지만, blueprint에 등록되는 함수는 login_required(func)가 아닌 func가 등록되게 됩니다.

따라서 login_required decorator가 적용된 함수를 blueprint에 등록할 수 있도록, @bp.route()가 맨 마지막에 적용되도록 해야 합니다.

양진혁

M 2021년 1월 22일 7:15 오후

@login_required
@bp.route
def func():

이렇게 하면 bp.route -> login_required 순으로 실행됩니다.

@bp.route
@login_required
def func():

이렇게 하면 login_required -> bp.route 순으로 실행되구요.

따라서 항상 login_required가 먼저 실행될 수 있도록 함수 바로 위에 써 주어야 합니다.

박응용

2021년 1월 21일 11:55 오전