Giter VIP home page Giter VIP logo

Comments (4)

RobbeSneyders avatar RobbeSneyders commented on May 27, 2024

Thanks @gaurav-triverus.

I submitted a PR which makes the request available to the security handlers. In combination with a custom before/after-request middleware, you should be able to implement this flow.

class CustomMiddleware:

    def __init__(self, next_app: ASGIApp):
        self.next_app = next_app

    def before_request(scope: Scope):
        # Code here. State can be stored on the scope.

    def after_request(scope: Scope):
        # Code here. State can be stored on the scope.

    async def __call__(self, scope: Scope, receive: Receive, send: Send) -> None:
        self.before_request(scope)
        await self.app(scope, receive, send)

app = connexion.FlaskApp(__name__)
app.add_middleware(CustomMiddleware, position=connexion.middleware.MiddlewarePosition.BEFORE_SECURITY)

You can then access the state via request.scope in your security handler.

from connexion.

gaurav-triverus avatar gaurav-triverus commented on May 27, 2024

Thanks @RobbeSneyders
Just to confirm, even after those changes flask g object is not accessible in security layer.
we will have to create a custom middleware to set variables to be used in throughout the lifespan?

from connexion.

RobbeSneyders avatar RobbeSneyders commented on May 27, 2024

Yes indeed @gaurav-triverus

g is only available within the context of the Flask application. Since Connexion 3's security functionality is performed by middleware wrapped around the Flask application, it's not possible to have access there.

from connexion.

JoelPelaezP avatar JoelPelaezP commented on May 27, 2024

Hi, I have some issues implementing this custom Middleware.

this is my code:

`class CustomMiddleware:
def init(self, next_app):
self.next_app = next_app

def before_request(self, scope):
    print('test app  -> CustomMiddleware before_request')
    print("scope => " + str(scope))

def after_request(scope):
    print('test app  -> CustomMiddleware after_request')

async def __call__(self, scope, receive, send) -> None:
    print('test app -> CustomMiddleware __call__')
    self.before_request(scope)
    await self.next_app(scope, receive, send)

def get_project_root_dir() -> str:
return os.path.dirname(os.path.dirname(file))

def decode_jwt(token):
print('test app--> in decode_jwt')

decoded_token = jwt.decode(
    token,
    "secret",
    algorithms=["HS256"],
    options=dict(require_exp=True, require_sub=True),
)

return decoded_token

def hellow_world():
print('test app -->', 'in hellow_world ')
stores = [{"name": "local flask app", "description": "local flask app to test connexion "}]
return {"stores": stores}

def create_app():
print('test app --> in create_app')
options = SwaggerUIOptions(swagger_ui_path="/docs")
app = connexion.FlaskApp(
name, specification_dir=get_project_root_dir(), swagger_ui_options=options
)

app.add_api(
    'openapi.yaml',
    swagger_ui_options=options,
    strict_validation=True,
    validate_responses=True
)

app.add_middleware(CustomMiddleware, position=connexion.middleware.MiddlewarePosition.BEFORE_SECURITY)

flask_app = app.app

@flask_app.before_request
def push_db():
    print('test app --> in @flask_app.before_request')

@flask_app.teardown_request
def close_db(exception=None):
    print('test app --> in @flask_app.teardown_request')

@flask_app.after_request
def access_log_end(response):
    print('test app --> in @flask_app.after_request')
    return response

app.run(host = "0.0.0.0",
        port=5000,
        )

if name == "main":
create_app()`

when running the code and testing the endpoint hellowworld I have 1 issue:

  1. Printing steps in the code shows that before_request in customMiddleware is called 2 times with different value for scope param.

Results:

test app --> in create_app
test app -> CustomMiddleware call
test app -> CustomMiddleware before_request
scope => {'type': 'lifespan', 'asgi': {'version': '3.0', 'spec_version': '2.0'}, 'state': {}, 'app': <connexion.middleware.main.ConnexionMiddleware object at 0x7fd76318a100>}
test app -> CustomMiddleware call
test app -> CustomMiddleware before_request
scope => {'type': 'http', 'asgi': {'version': '3.0', 'spec_version': '2.3'}, 'http_version': '1.1', 'server': ('172.22.0.2', 5000), 'client': ('172.22.0.1', 44230), 'scheme': 'http', 'root_path': '', 'headers': [(b'host', b'localhost:5000'), (b'connection', b'keep-alive'), (b'sec-ch-ua', b'"Chromium";v="122", "Not(A:Brand";v="24", "Google Chrome";v="122"'), (b'accept', b'application/json'), (b'sec-ch-ua-mobile', b'?0'), (b'authorization', b'Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1c2VyIjoiYWRtaW4ifQ.LmuLCvLRfzvDVYK_iUBmwL3-5K9N0QLFrHwhXVb5TPU'), (b'user-agent', b'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/122.0.0.0 Safari/537.36'), (b'sec-ch-ua-platform', b'"Windows"'), (b'sec-fetch-site', b'same-origin'), (b'sec-fetch-mode', b'cors'), (b'sec-fetch-dest', b'empty'), (b'referer', b'http://localhost:5000/docs/'), (b'accept-encoding', b'gzip, deflate, br, zstd'), (b'accept-language', b'en-US,en;q=0.9,es-US;q=0.8,es;q=0.7'), (b'cookie', b'_ga=GA1.1.1667569712.1706132845; _ff={%22enableLocalizeVietnameseLanguage%22:false}; _ga_SW2TVH2WBY=GS1.1.1708531929.9.1.1708540204.0.0.0')], 'state': {}, 'method': 'GET', 'path': '/hellowworld', 'raw_path': b'/hellowworld', 'query_string': b'', 'app': <connexion.middleware.main.ConnexionMiddleware object at 0x7fd76318a100>, 'starlette.exception_handlers': ({<class 'starlette.exceptions.HTTPException'>: <function ExceptionMiddleware.http_exception at 0x7fd7634a0e50>, <class 'starlette.exceptions.WebSocketException'>: <bound method ExceptionMiddleware.websocket_exception of <connexion.middleware.exceptions.ExceptionMiddleware object at 0x7fd762d2c5b0>>, <class 'connexion.exceptions.ProblemException'>: <function ExceptionMiddleware.problem_handler at 0x7fd762d3ab80>, <class 'Exception'>: <function ExceptionMiddleware.common_error_handler at 0x7fd762d3ac10>}, {}), 'path_params': {}, 'extensions': {'connexion_routing': {'api_base_path': '', 'operation_id': 'app.hellow_world'}}}
test app--> in decode_jwt
test app --> in @flask_app.before_request
test app --> in hellow_world
test app --> in @flask_app.after_request
test app --> in @flask_app.teardown_request
INFO: 172.22.0.1:44230 - "GET /hellowworld HTTP/1.1" 200 OK

from connexion.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.