Empresas
Empleos
  • Sobre nosotros
  • Soluciones
    • Publicación de vacantes
      Publica tu vacante y recibe candidatos calificados en 48h.
    • Evaluación de candidatos
      500+ pruebas técnicas y psicológicas, más anti-fraude.
    • Headhunting
      Búsqueda ejecutiva a la medida de principio a fin.
    • Nómina + EOR
      Dispersión de nómina y EOR en más de 15 países de LATAM.
  • Precios
  • Empleos

0

428
Vistas
Flask: how to register a wrapper to all methods

I've been moving from bottle to flask. I'm the type of person that prefers writing my own code instead of downloading packages from the internet if I the code needed is 20 lines or less. Take for example support for Basic authentication protocol. In bottle I could write:

def allow_anonymous():
    """assign a _allow_anonymous flag to functions not requiring authentication"""
    def wrapper(fn):
        fn._allow_anonymous = True
        return fn
    return wrapper


def auth_middleware(fn):
    """perform authentication (pre-req)"""
    def wrapper(*a, **ka):
        # if the allow_anonymous annotation is set then bypass this auth
        if hasattr(fn, '_allow_anonymous') and fn._allow_anonymous:
            return fn(*a, **ka)
        user, password = request.auth or (None, None)
        if user is None or not check(user, password):
            err = HTTPError(401, text)
            err.add_header('WWW-Authenticate', 'Basic realm="%s"' % realm)
            return err
        return fn(*a, **ka)
    return wrapper

...

app = Bottle()
app.install(middleware.auth_middleware)

The above code gave me full support for basic auth protocol for all methods unless explicitly decorated with the @allow_anonymous wrapper. I'm just a beginner with flask. I'm having a hard time accomplishing the bottle-compatible code above in flask without adding dependencies on more python packages or excessive boiler-plate. How is this handled directly and clearly in flask?

over 4 years ago · Santiago Trujillo
2 Respuestas
Responde la pregunta

0

You can definitely some of the functionality of flask-httpauth yourself, if you wish :-P

I would think you will need to play some before_request games (not very beautiful), or alternatively call flask's add_url_rule with a decorated method for each api endpoint (or have a route decorator of your own that will do this). The add_url_rule gets a view function that is usually your api endpoint handler, but in your case, will be a wrapped method in a manner very much like the one you gave in the post (auth_middleware).

The gist of it:

from flask import Flask, make_response, request

app = Flask(__name__)

def view_wrapper(fn):
    """
    Create a wrapped view function that checks user authorization
    """
    def protected_view(*a, **ka):
        # if the allow_anonymous annotation is set then bypass this auth
        if hasattr(fn, '_allow_anonymous') and fn._allow_anonymous:
            return fn(*a, **ka)
        # consult werkzeug's authorization mixin
        user, password = (request.authorization.username, request.authorization.password) if request.authorization else (None, None)
        if user is None or not check(user, password):
            err_response = make_response(text, 401)
            err_response.headers['WWW-Authenticate'] = 'Basic realm="%s"' % realm
            return err_response
        return fn(*a, **ka)

    return protected_view


# An endpoint
def hello():
    return 'hello there'

app.add_url_rule('/', 'hello', view_wrapper(hello))

Of course, this can (and should) be further enhanced with Blueprints, etc.

over 4 years ago · Santiago Trujillo Denunciar

0

Note #1: this is cribbed from separate answers in SO.

Note #2: this doesnt use blueprints. Again, I'm new to flask and I appreciate that blueprints will help the app scale but one step at a time...

def allow_anonymous(decorated_function):
    decorated_function.is_public = True
    return decorated_function

@app.before_request
def auth_middleware():
    fn = app.view_functions[request.endpoint]
    if hasattr(fn, 'allow_anonymous') and fn.allow_anonymous:
        # anonymous permitted
        return
    elif my_custom_authentication():
        # anonymous not permitted authentication succeeded
        return
    else:
        # anonymous not permitted authentication failed
        err_response = make_response(text, 401)
        err_response.headers['WWW-Authenticate'] = 'Basic realm="%s"' % realm
        return err_response

@app.route('/public_thing')
@allow_anonymous
def public_thing():
   return 'yo'

@app.route('/regular_thing')
def regular_thing():
   return 'if you can read this youre authenticated.'

over 4 years ago · Santiago Trujillo Denunciar
Responde la pregunta
Encuentra empleos remotos

¡Descubre la nueva forma de encontrar empleo!

Top de empleos
Top categorías de empleo
Empresas
Publicar vacante Precios Comercial
Legal
Términos y condiciones Política de privacidad
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Recomiéndame algunas ofertas
Necesito ayuda