Slim PHP Framework middleware custom URL filter

2.2k views Asked by At

I am creating API using Slim Framework. I need to filter requests required authentication and route them to the specific auth handler. Or it would be better to say that I need to filter URI that don't require auth (public information).

I have created following middleware skileton

class TokenAuth extends \Slim\Middleware {
    private $auth;
    public function __construct($userEmail,$accesToken,$appSecret) {

    }

    /**
     * Deny Access
     *
     */
    public function deny_access() {
        $res = $this->app->response();
        $res->status(401);
    }


    public function authenticate($token) {
        ....
    }

    /**
     * Call
     *
     */
    public function call() {
        //Get the token sent from jquery

        $tokenAuth = $app->request->headers->get('Authorization');

        //Check if our token is valid
        if ($this->authenticate($tokenAuth)) {
        ....
        } else {
            $this->deny_access();
        }
    }

}

In this case I cannot access any URI without token, how to solve this problem, allowing access to the public resources.
I would be grateful for any help. Thx in advance.

2

There are 2 answers

2
robinef On BEST ANSWER

You have mainly two ways of doing it :

Global middleware

One way consist in adding an OAuth middleware to your API so you can check if user is authenticated or not and setup a flag, then inside each route you can do a simple check if user is authenticated or not.

<?php
$app = new \Slim\Slim();
$app-authenticated = false;
$app->add(new MyOAuthMiddleware());

Then your MyOAuthMiddleware :

<?php
 class MyOAuthMiddleware extends \Slim\Middleware {
  public function call() {
   //Do your OAUTH check stuff here
   $this->app-authenticated = true;
  }
}

Now you can check in all your routes :

<?php
$app->get('/hello/:name', function ($name) {
   $app = \Slim\Slim::getInstance();
   if($app->authenticated === true){
    echo "Hello, $name";
   } else {
    echo "You need to login";
   }
});

Specific route middleware

You can follow Slim documentation and choose to add your Middleware directly on each declaration :

<?php
$authenticateForRole = function ( $role = 'member' ) {
    return function () use ( $role ) {
        $user = User::fetchFromDatabaseSomehow();
        if ( $user->belongsToRole($role) === false ) {
            $app = \Slim\Slim::getInstance();
            $app->flash('error', 'Login required');
            $app->redirect('/login');
        }
    };
};
$app = new \Slim\Slim();
$app->get('/foo', $authenticateForRole('admin'), function () {
    //Display admin control panel
});
0
John Cartwright On

A common strategy here is to implement a firewall with rules.

A very simple firewall might ignore public assets (i.e., anything ending in .jpg, .png, .css, .js, etc.). Rules are commonly simply regular expressions.

An example firewall configuration might look like (note the order the rules are applied are also important).

firewalls:
    # Public assets, anyone can see
    assets:
        expression: \.(js|css)$
        auth: false

    # Everything exception login requires auth
    secure:
        expression: ^(?!login$)
        auth: true

    # Everything else gets through
    public:
        expression: ^/
        auth: false

Have you framework parse the definition and iterate over the rules. From there, you can decide how to handle the routing.