I think it is very cool openresty works with lua instead of javascript. But the given example lets me wonder about its practical use:
Suppose before forwarding the data POSTed to your application you want to do certain checks on the data so that you can be sure that your application receives only the clean refined data to operate upon. (...) So your application layer can focus on working upon it without worrying about cleansing it first.
I would think that dealing with incorrect data should be handled by the application rather than nginx. If you want to expose your application via other means it means you don't have to duplicate your validation logic. Think also about giving feedback about the incorrect POST-data, I think your application is better suited to provide that, as it can return a <form> with carefully placed messages for instance.
On the face of it that's not very practical indeed, but that doesn't mean it isn't necessary in real-world scenarios. You don't always control the applications behind your nginx reverse proxies and can't always enforce correct behavior from them. They may come from a separate group which you can't easily reach for political reasons or from some external vendor with its own roadmap.
This makes OpenResty a nice tool for operations/security, because you have enough control to implement workarounds when required without having to wait for external entities. Some of you may cringe at the notion of implementing workarounds, but that's standard practice in any corporate setting. The alternative is just worse and you learn to live with it by calling it "application firewalls".
The other nice thing about OpenResty is the flexibility gained from separating scaling/infrastructure logic from application logic. And this got even better in the last relase of the Lua module by allowing custom balancing logic in upstream blocks without having to hook into header_filter_by_lua or something like that to manipulate the URL to feed into proxy_pass.
Finally, there's microservice (or microapplication) architectures, where your big application is really a bunch of smaller applications being glued together by logic in nginx (something like Edge Side Includes but nicer).
> I would think that dealing with incorrect data should be handled by the application rather than nginx. If you want to expose your application via other means it means you don't have to duplicate your validation logic. Think also about giving feedback about the incorrect POST-data, I think your application is better suited to provide that, as it can return a <form> with carefully placed messages for instance.
A good chunk of traffic is bot exploit traffic and rejecting that silently at the proxy level is a viable option [its basically what Cloudflare, among others, use OpenResty for].
Incorrect data should go to the application, malicious data should be dropped before it gets there if practical.
What I wanted to say was.. openresty is like a second application server + proxy combined into one. So you can
have some of your validation at proxy level itself and reject dirty data then and there without ever having to bother your application server.
>as it can return a <form> with carefully placed messages for instance.
Openresty can also do that. The choice may vary from person to person. But the point I was trying to make was that if I have to use nginx I'd rather use openresty. And if I use openresty I'd probably do all little tasks like validation at the proxy level itself.
I agree that's a bad use case for openresty. But by the same token, you can move logic that doesn't belong in a particular application to a simple lua script, perhaps with delegation to another service. So in general, I think, openresty helps improve separation of concerns rather than hurting it.
Openresty is fantastic. On a static website I did last year I implemented some basic login with it and some Elasticsearch full text search. If you just need some very simple REST API and don't want to start with a full blown backend server you can just script some pretty powerful stuff with it.
Since a few weeks ago Openresty also has "..._by_lua_block" directives that allow you to just write some lua straight into the config without having to escape the lua code:
Yup, we love it. I moved to it a few years ago and it's worked fantastically. We've used it for everything from debugging access to newer services by simply including additional headers (in a staging environment of course) to blocking older versions of clients (we make games, there have been odd ways people cheat) to much more fluid handling of CORS, to direct access to Redis for fast polling for older devices that don't support web socket connections and more. This, of course, was all before the JavaScript interpreter was added to nginx proper, but I feel no need to move over to JavaScript so long as open resty stays supported.
I had an idea for microservice deployments: to send all incoming requests through an authenticator script, that will verify request tokens with the auth-server, and extract the user's context to some other request parameter (e.g. custom header). The benefit would be that all microservices no longer need to worry about the authorisation of incoming requests, as this is abstracted away to nginx. In this way we know that if a request reaches the target service, it has already been authorised, thus simplifying the services and removing the dependency on the auth-server, and decreasing the burden of testing these services. It works nicely.
Right on. I've implemented that sort of pattern in a couple of jobs in the last few years and its seemed to work out well. The abstraction between 1 piece of code needing to know & understand oauth vs. every piece of code is a total win in my book.
This is a great idea actually. I do something like that myself where I've exposed a couchdb instance publically but the access through it is controlled by access_by_lua. I use basic authentication instead of token based auth but the principle is the same.
See my toplevel post. Our customers love using `access_by_lua` to delegate authentication and authorization to our service. Obviously you can use your own authorization and and access control to accomplish the same thing, in the same way.
My employer sells an authorization and access control engine that can be queried by simple REST calls. We produced a small lua module that makes it simple to use from an `_by_lua_` directive.
Our customers (and internal teams) love it -- for the most part they use it to provide basic access control to simple web services, but some have done really sophisticated things things, such as deciding what privileges an HTTP request requires based on the body, query parameters, method, and headers.
HTTP clients can simply provide an authentication token issued by our services in a header, and everything works like magic.
At some point we were considering writing our own nginx module, and while we have the engineering talent to pull this off, OpenResty is just so much simpler, so it won the day hands down.
Suppose before forwarding the data POSTed to your application you want to do certain checks on the data so that you can be sure that your application receives only the clean refined data to operate upon. (...) So your application layer can focus on working upon it without worrying about cleansing it first.
I would think that dealing with incorrect data should be handled by the application rather than nginx. If you want to expose your application via other means it means you don't have to duplicate your validation logic. Think also about giving feedback about the incorrect POST-data, I think your application is better suited to provide that, as it can return a <form> with carefully placed messages for instance.