thephpleague / route

Fast PSR-7 based routing and dispatch component including PSR-15 middleware, built on top of FastRoute.
http://route.thephpleague.com
MIT License
651 stars 126 forks source link

Multiple middleware on a route/route group. #196

Closed alturic closed 6 years ago

alturic commented 6 years ago

I've read the docs (http://route.thephpleague.com/4.x/middleware/), and I understand you can have multiple middleware, but I don't think it's multiple middleware like I'm thinking.

Ex:

$router->group('/lessons', function ($router) { $router->map('GET', '/php/', 'ControllerFoo::index'); $router->map('GET', '/reactjs/', 'ControllerBar::index'); })->middle(new App\AuthMiddleware);

So, say you have a group (or even if you had to define it for each route) that everything inside required an authentication middleware. Then a specific route also requires a middleware to check if they have a access to said route. How would you achieve that? In the above example, to just access anything under /path you have to be logged in. However, to access /path/foo you need to have access to that, and to access /path/bar you need to have access to that. Think subscription service, you can subscribe to PHP course, ReactJS courses, or both.

I don't mind if each route wouldn't be able to be contained inside a single group, the main question is how exactly would you define a "check auth middleware, then check PhpSubscription or ReactJSSubscription middleware"?

Almost something like:

$router->group('/lessons', function ($router) { $router->map('GET', '/php/', 'ControllerFoo::index')->middle(new App\PhpMiddleware); $router->map('GET', '/reactjs/', 'ControllerBar::index')->middle(new App\ReactJSMiddleware); })->middle(new App\AuthMiddleware);

The groups middleware is checked, then the route(s) specific middleware is checked.

Pumpuli commented 6 years ago

Isn't that exactly how it's done? The group middleware is the outer middleware and if it calls handle(), then the next middleware is executed, in this case the route specific middleware.

Note that it seems that there's currently a bug with the group middleware, which causes them to be executed twice: #195.

alturic commented 6 years ago

Isn't that exactly how it's done? The group middleware is the outer middleware and if it calls handle(), then the next middleware is executed, in this case the route specific middleware.

Note that it seems that there's currently a bug with the group middleware, which causes them to be executed twice: #195.

Interesting, I didn't know you could define a group middleware, and route inside of the group middleware.

If you didn't have a group though, does this work too then? I swore, at least when I last tried on 3.x it didn't work this way.

$router->map('GET', '/php/', 'ControllerFoo::index')->middle(new App\AuthMiddleware, new App\PhpMiddleware);

Pumpuli commented 6 years ago

That should be correct, except the method is called middleware() instead of middle() (There's also middlewares() in 4.x).

philipobenito commented 6 years ago

There was a complete overhaul of middleware in 4.x, I wasn’t happy with the execution chain.

Since 4.x though this is exactly how it works. You can add your auth middleware to the group and that will run for any route matched in that group, you can also add middleware to each individual route in a group.

As mentioned, there is a bug at the moment but that doesn’t have any effect on how the middleware is defined though, the fix will get a release this week.

I’ll close this for now but feel free to continue discussion.