Slim PHP: Only catch valid routes with middleware

前端 未结 3 847
遥遥无期
遥遥无期 2020-12-20 17:51

I\'m writing a REST API with Slim. I have written a small middleware to protect the resources so only authenticated users will be able to access them:



        
相关标签:
3条回答
  • 2020-12-20 18:27

    Not exactly what you asking for, but personnaly when i need to check authentification on some routes i do it like this.

    config:

    $config = array(
        ...,
    
        'user.secured.urls' => array(
            array('path' => '/user'),
            array('path' => '/user/'),
            array('path' => '/user/.+'),
            array('path' => '/api/user/.+')
        ),
        ...
    
    );
    

    middleware:

    /**
     * Uses 'slim.before.router' to check for authentication when visitor attempts
     * to access a secured URI.   
     */
    public function call()
    {
        $app = $this->app;
        $req = $app->request();
        $auth = $this->auth;
        $config = $this->config;
    
        $checkAuth = function () use ($app, $auth, $req, $config) {
    
            // User restriction
            $userSecuredUrls = isset($config['user.secured.urls']) ? $config['user.secured.urls'] : array();
            foreach ($userSecuredUrls as $url) {
                $urlPattern = '@^' . $url['path'] . '$@';
                if (preg_match($urlPattern, $req->getPathInfo()) === 1 && $auth->hasIdentity() === false) {
    
                $errorData = array('status' => 401,'error' => 'Permission Denied');
                $app->render('error.php', $errorData, 401);
                $app->stop();                   
            }
        }
    
        };
    
        $app->hook('slim.before.router', $checkAuth);
    
        $this->next->call();
    }
    

    but if almost all your routes need authentification maybe not the best solution.

    great example: http://www.slideshare.net/jeremykendall/keeping-it-small-slim-php

    0 讨论(0)
  • 2020-12-20 18:35

    Maybe my implementation will work for you:

    <?php
    
    class CustomAuth extends \Slim\Middleware {
    
        public function hasRoute() {
            $dispatched = false;
    
            // copied from Slim::call():1312
            $matchedRoutes = $this->app->router->getMatchedRoutes($this->app->request->getMethod(), $this->app->request->getResourceUri());
            foreach ($matchedRoutes as $route) {
                try {
                    $this->app->applyHook('slim.before.dispatch');
                    $dispatched = $route->dispatch();
                    $this->app->applyHook('slim.after.dispatch');
                    if ($dispatched) {
                        break;
                    }
                } catch (\Slim\Exception\Pass $e) {
                    continue;
                }
            }
    
            return $dispatched;
        }
    
        public function call() {
    
            if ($this->hasRoute()) {
                if ($authorized) {
                    $this->next->call();
                }
                else {
                    $this->permissionDenied();
                }
            }
            else {
                $this->next->call();
            }
        }
    }
    
    0 讨论(0)
  • 2020-12-20 18:52

    I use a hook to do what you're trying to do, as MamaWalter suggested, but you want to use slim.before.dispatch rather than an earlier hook. If the route your user is trying to visit doesn't exist, the hook will never be called and the 404 gets thrown.

    I'm doing exactly that in my own Authorization Middleware. Works like a charm.

    0 讨论(0)
提交回复
热议问题