Slim framework JWT middleware Issue

2019-09-06 10:56发布

问题:

I'm having a problem with my slim app, I'm trying to use JsonWebToken for authentication but I don't know how to do it the right way.

My middleware is blocking all the requests that dont include a valid token, but what about the first authentication post request that obviously don't include a valid token. Here's my code if it helps (in middleware file):

$app->add(function (Request $request,Response $response, $next) use ($app){
    $stringToken = $request->getHeader("Authorization")[0];
    if($stringToken == NULL) {
        return $response->withJson(array("Connection"=>"Fail On Token", "Error"=>"No token Provided."));
    } else {
        $jsonObjectToken = json_decode($stringToken);
        try{
            JWT::decode($jsonObjectToken->jwt, JWTController::$secretKey, array('HS512'));
        }catch (Exception $e){
            return $response->withJson(array("Connection"=>"Fail On Token", "Error"=>$e->getMessage()));
        }
        $response = $next($request, $response);

        return $response;
    }
});

回答1:

You can check which route is called inside the middleware and then do not check the token of the current route is the actual login route.

For getting the route inside the middleware you need first to configure slim to determinate the route before the middleware gets executed:

use Slim\App;

$app = new App([
    'settings' => [
        'determineRouteBeforeAppMiddleware' => true
    ]
])

Then you can access the current route with $route = $request->getAttribute('route'); inside the middleware:

You now can check if the current route is the login route

$app->add(function (Request $request, Response $response, callable $next) {
    $route = $request->getAttribute('route');
    $name = $route->getName();

    if($name !== 'login') {
        // do authentication
    } 

    return $next($request, $response);
});

Note: You need to set the name of the Route with ->setName($name) on the route like so:

$app->get('/login', function ($request, $response, $args) {
    // do something
})->setName('login');