1

Flask-HTTPAuth를 사용하여 기본 인증을 사용하여 2 단계 인증 시스템을 만들려고합니다. 신청서에는 두 가지 경로가 있습니다. 기본 경로는 /이며, 로그인 한 사용자는 누구나 액세스 할 수 있습니다. /admin의 관리 경로는 관리자로 로그인 한 사용자 만 액세스 할 수 있습니다. 이 미세 너무 오래 작동데코레이터 체인을 통해 Flask-HTTPAuth를 사용하여 권한있는 사용자를 만드십시오 --- 컨텍스트를 잃어 버리십니까?

@auth.verify_password 
def verify_pw(lastname, password): 
    ln = lastname.lower() 
    if ln in dbops.list_users(): 
     hashed_pw = dbops.find_hashed_password(ln) 
     return bcrypt.checkpw(password.encode('utf8'), hashed_pw.encode('utf8')) 
    return False 

def must_be_admin(f): 
    @wraps(f) 
    def wrapper(*args, **kwargs): 
     if dbops.is_admin(auth.username()): 
      return f(*args, **kwargs) 
     return "Not authorized." 
    return wrapper 

@core.route("/") 
@auth.login_required 
def dataentry(): 
    return render_template("dataentry.html") 

@core.route("/admin") 
@must_be_admin 
@auth.login_required 
def admin(): 
    return render_template("admin.html") 

:

그래서 나는 다음 (여기서 dbops 바로 데이터베이스에 이야기 처리하는 네임 스페이스)와 같은 코드의 관련 부분, 장식 체인하여이를 구현하기로 결정 관리자 사용자로 로그인하려는 사용자는 먼저 / 경로를 방문합니다. 사용자 이름과 비밀번호를 묻는 메시지가 표시되면 관리자 사용자는 /admin으로 이동하여 로그인 관리 작업을 수행 할 수 있습니다.

그러나 관리자 사용자가 처음으로 /admin을 방문하면 로그인 프롬프트가 표시되지 않습니다. 그냥 던져, 디버거에서 주위에 파고 후 auth.username() 빈 문자열을 반환하는 것을 결정했습니다. 그래서 내 추측은 어떤 이유로 내부의 데코레이터가 적용되지 않아 로그인 프롬프트가 없다는 것입니다.

여기에서 어떤 일이 벌어 질지 아는 사람이 있습니까?

내 첫 번째 가설은 관리 용 장식 자의 내부 기능이 is_admin 검사가 끝날 때까지 호출되지 않았기 때문에 이것이 쉬운 버그라는 것입니다. 다음과 같이 그래서 나는, 내 함수를 호출 --- 따라서 아마도 체크하기 전에 --- auth.username() 사용할 수 있도록하는 것이 해결하기 위해 노력 :

def must_be_admin(f): 
    @wraps(f) 
    def wrapper(*args, **kwargs): 
     dummy_to_get_username = f(*args, **kwargs) 
     if dbops.is_admin(auth.username()): 
      return dummy_to_get_username 
     return "Not authorized." 
    return wrapper 

을하지만 그건 그냥 같은 문제가 발생합니다.

this prior SO에서 라이브러리 작성자가 권장하는 방법은 두 개의 개별 Flask-HTTPAuth 개체를 만드는 것입니다. 나는 할 수있어. 문제 없어. 그러나 장식가가 어떻게 작동하는지에 대한 내 정신 모델은 분명히 실패하고 있습니다. 그래서 저는이 문제를 작업하고 싶은 기능을 얻는 것과는 독립적으로 해결하고 싶습니다 ...

답변

1

데코레이터를 적용하는 정확한 순서는 밖으로 데려 오지 만 불행히도 잘못된 순서는 응용 프로그램이 잘못 작동하게합니다.

"전에"뷰 기능을 실행하는 데코레이터의 경우 일반적으로 데코레이터를 실행하려는 순서대로 데코레이터를 배치해야합니다. 그래서 코드를 사용할 때 당신은 무엇을 기대 할 것이라고 생각 플라스크-HTTPAuth의 login_required 전에 must_be_admin :이 방법으로

@core.route("/admin") 
@auth.login_required 
@must_be_admin 
def admin(): 
    return render_template("admin.html") 

는 자격 증명을 먼저 확인되며,이 잘못되었거나 누락 된 경우 login_required가 401 오류를 반환합니다 브라우저에 로그인하면 로그인 프롬프트가 나타납니다. 자격 증명이 유효하다고 판단 된 후에 만 ​​관리자 꾸미기를 평가하려고합니다.

+0

정말 고마워요! 여기 모든 플라스크 질문에 적극적으로 참여한 것은 대단한 일입니다. –