Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Question: How can I add a filter to certain groupted routes? #250

Open
Aristona opened this issue Oct 20, 2014 · 11 comments
Open

Question: How can I add a filter to certain groupted routes? #250

Aristona opened this issue Oct 20, 2014 · 11 comments
Assignees

Comments

@Aristona
Copy link

Hi,

I have a route group like:

$klein->with('/api/something/', function () use ($klein) {

    // Auth here

    $klein->respond('GET', 'test', function($req, $res, $service, $app) {
          ...
    });

});

I have different groups of API. Everything under /api/something/ requires HTTP basic auth but it should only work for that instance. (e.g api/somethingElse doesn't require an auth.)

Basically, something like:

$klein->with('/api/something/', function () use ($klein) {

    if( \Auth::unauthorized() )
    {
         throw new \AuthException("You need to provide basic HTTP Auth credentials.");
    }

    $klein->respond('GET', 'test', function($req, $res, $service, $app) {
          ...
    });

});

I'm not sure how it is possible with klein. The check above affects application globally and every route group requires auth credentials.

Any ideas?

@Rican7
Copy link
Member

Rican7 commented Oct 20, 2014

Try something like this:
#122 (comment)

@Rican7 Rican7 self-assigned this Oct 20, 2014
@Aristona
Copy link
Author

Hi,

Trying the following code:

$klein->with('/api/', function () use ($klein) {

    $klein->respond(function() {
        throw new \Exception("Test.");
    });

    $klein->respond('GET', 'test', function($req, $res, $service, $app) {
        return "hello";
    });

});

It never throws the test exception. If I remove the test route, or simply call /api/ endpoint, it still doesn't run the exception callback. Any ideas?

Also, with the following code:

    $klein->respond(function () {

        $user = "test"; //$_SERVER['PHP_AUTH_USER'];
        $pass = "boo";  //$_SERVER['PHP_AUTH_PW'];

        if($user !== "test" && $pass !== "boo")
        {
            throw new \Exception("Invalid authorization credentials on related API.");
        }

    });

I am having "Parse error: syntax error, unexpected 'if' (T_IF)". Am I overlooking something?

My whole front controller looks like this:

define('APPLICATION_START', microtime(true));

$klein = new \Klein\Klein();

$klein->onHttpError(function ($code, $router) {
    switch ($code) {
        case 404:
            $router->response()->code($code);
            $router->response()->json(['message' => 'Requested endpoint not found.']);
            break;
        default:
            $router->response()->code($code);
            $router->response()->json(['message' => 'Oh no, a bad error happened that caused a '. $code]);
    }
});

require_once __DIR__ . "/../routes.php"; // Where I store klein routes.

try {

    $klein->dispatch();

}

catch(Exception $e)
{
    logMessage($e->getMessage());

    $klein->response()->header('Access-Control-Allow-Origin', '*');
    $klein->response()->header('Access-Control-Allow-Methods', 'GET');
    $klein->response()->code(400);

    if($klein->request()->param('callback') !== NULL)
    {
        return $klein->response()->json(['message' => $e->getMessage()], $klein->request()->param('callback'));
    }
    else
    {
        return $klein->response()->json(['message' => $e->getMessage()]);
    }

}

define('APPLICATION_END', microtime(true));

@Rican7
Copy link
Member

Rican7 commented Oct 23, 2014

Really? Its not working?
Hmm... what version of Klein are you using? The latest master commit or a tagged stable release?

I just linted your code and it doesn't seem to have any issues. I'm not sure what would be causing your parse error here. :/

@Aristona
Copy link
Author

"klein/klein": "dev-master", in my composer.json. Yes, it doesn't work. The following:

$klein->with('/api/test/', function () use ($klein) {

    $klein->respond(function () {
        echo "hi";
    });

    $klein->respond('GET', 'moo', function($req, $res, $service, $app) {
        echo "hey";
    });

});

outputs "hey" when I browse /api/test/moo.

Oh, by the way, we use Laravel in our application. For the API, I forwarded /api/ calls with .htaccess to /public/api.php -

api.php has: require __DIR__.'/../api/bootstrap/autoload.php';

api/bootstrap/autoload has:

require __DIR__.'/../vendor/autoload.php';
require_once __DIR__ . '/start.php';

start.php has:

define('APPLICATION_START', microtime(true));

$klein = new \Klein\Klein();
...

Not sure if this causes the problem. (which I doubt but it is really odd)

@Rican7
Copy link
Member

Rican7 commented Oct 24, 2014

Ooooo, I think I might know why. It might be because you're with() call has the route with a trailing slash.

Try changing the path from /api/test/ to /api/test/? (optional trailing slash)

@Aristona
Copy link
Author

@Rican7 Oh, yeah that was the case. It works properly now. Perhabs we should add it to documentation?

@Rican7
Copy link
Member

Rican7 commented Oct 28, 2014

Yea, we could, maybe a note of some kind. Its really just because of the way the server software (not Klein) was interpreting the path and redirecting you away from the trailing slash (most likely).

Its out of Klein's hands there, but yea, I might make trailing slashes a bit less of a pain in a later version.

@Aristona
Copy link
Author

Aristona commented Apr 6, 2015

Hey @Rican7 , is there any way to respond codes via filter function?

 $klein->respond(function ($req, $res, $service, $app) {

        // If http basic auth credentials doesn't exists
                return $res->code(401);

 });

 // Actual routes

Is it doable in the current state of framework? Right now requests still go to the actual route, unless I do something like die in the filter function. What would be a good way to solve this?

@Rican7
Copy link
Member

Rican7 commented Apr 6, 2015

@Aristona If you really want to "stop" the routing and halt with a 401 code, you probably want to use abort() instead.

@Aristona
Copy link
Author

Aristona commented Apr 8, 2015

Oh, I did a ctrl f "abort" on the main page but couldn't find anything, so I assumed there is no such method.

Abort will definitely solve my issue, thanks!

@Aristona
Copy link
Author

@Rican7 Hey, sorry to disturb again. I cannot get it to work. My code looks like:

$klein->with('/v1/?', function () use ($klein) {

    /*
    |   Before filter.
    */
    $klein->respond(function ($req, $res, $service, $app) use ($klein) {

           try {

                  $klein->abort(401);

           } catch (Exception $e) {

                  return false;
          }
    });

    // Actual route

Do you know what could be the issue? I also tried $app->abort(), no luck.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

2 participants