slim-jwt-auth icon indicating copy to clipboard operation
slim-jwt-auth copied to clipboard

How does the before/after parameter work?

Open NeftaliAcosta opened this issue 11 months ago • 1 comments

I am using the plugin and I need to perform some validations after validating the token. In this sense, my app only allows a single login from devices, therefore, I validate that the token received is equal to the last token generated, if not, I should not accept requests and return a 401 message, however, My code does not work, since after performing the corresponding validations it continues with the flow without stopping after doing the validations.

Can you help me, please? Thank you so much.

` return function (App $app) { $key = $_ENV['JWT_AUTH_KEY']; $app->add(SessionMiddleware::class);

$app->add(
    new Tuupola\Middleware\JwtAuthentication([
        "header" => "Authorization",
        "attribute" => "jwt",
        "secure" => true,
        "path" => "/",
        "ignore" => [
            "/auth/validate",
            "/auth/recovery-password",
            "/auth/reset-password",
            "[/]"
        ],
        "secret" => $key,
        "before" => function ($request, $arguments) {
            // Get values requires
            $token = $request->getHeaders('Accept')['Authorization'][0];
            $token = str_replace('Bearer ', '', $token);
            try {
                // Instance User object
                $oUser = new Users();
                $ssid = json_decode($oUser->getSsid());
                if (
                    $ssid->jwt !== $token) {
                    // this code does not work
                    $response = new Response();
                    $response = $response->withStatus(401);
                    $response->getBody()->write('Unauthorized');
                    return $response;
                }
            } catch (UserNotFoundException $e) {
                // this code does not work
                $response = new Response();
                $response = $response->withStatus(401);
                $response->getBody()->write('Unauthorized');
                return $response;
            }

            return true;
        },
        "error" => function ($response, $arguments) {
            $data["statusCode"] = $response->getStatusCode();
            $data["message"] = ["Exception" => [$arguments["message"]]];
            $data["data"] = [];

            $response->getBody()->write(
                json_encode($data, JSON_UNESCAPED_SLASHES | JSON_PRETTY_PRINT)
            );

            return $response->withHeader("Content-Type", "application/json");
        }
    ])
);

}; `

Update:

I have updated my code like this, and it partially works, it already returns the response I want, but I cannot stop the flow and it also returns the response from the endpoint I am accessing:

` return function (App $app) { $key = $_ENV['JWT_AUTH_KEY']; $app->add(SessionMiddleware::class);

$app->add(
    new Tuupola\Middleware\JwtAuthentication([
        "header" => "Authorization",
        "attribute" => "jwt",
        "secure" => true,
        "path" => "/",
        "ignore" => [
            "/auth/validate",
            "/auth/recovery-password",
            "/auth/reset-password",
            "users/",
            "/dictionary",
            "[/]"
        ],
        "secret" => $key,
        "after" => function (Response $response, $arguments) {
            // Get values requires
            $token = $arguments['token'];
            $uuid = $arguments['decoded']['uuid'];
            // Instance User object
            $oUser = new Users();
            $id = $oUser->getIdFromUuid($uuid);
            $oUser = new Users($id);
            $ssid = json_decode($oUser->getSsid());
            if (
                $ssid->jwt !== $token ||
                $ssid->sid !== $arguments['decoded']['sid'] ||
                $ssid->uuid !== $arguments['decoded']['uuid']
            ) {
                $data["statusCode"] = 401;
                $data["message"] = ["Exception" => ["Token not valid for this session."]];
                $data["data"] = [];
                $response = $response->withStatus(401);
                $response->getBody()->write(json_encode($data, JSON_UNESCAPED_SLASHES | JSON_PRETTY_PRINT));
                return false;
            }
        },
        "error" => function ($response, $arguments) {
            $data["statusCode"] = $response->getStatusCode();
            $data["message"] = ["Exception" => [$arguments["message"]]];
            $data["data"] = [];

            $response->getBody()->write(
                json_encode($data, JSON_UNESCAPED_SLASHES | JSON_PRETTY_PRINT)
            );

            return $response->withHeader("Content-Type", "application/json");
        }
    ])
);

};

`

Response:

image

NeftaliAcosta avatar Mar 28 '24 05:03 NeftaliAcosta

@NeftaliAcosta having the middleware also try and handle error logic isn’t ideal. The ‘after’ option is designed to modify the response which gets passed to the next middleware.

A better way of doing is by throwing a custom exception and handle this in your error handling.

better yet just write a custom middleware with this logic.

JimTools avatar Mar 29 '24 09:03 JimTools