Hi! The rowCount method is for INSERT and UPDATE commands and returns the number of affected rows. You may try to use the result of the fetch method instead for a SELECT statement.
I do have insert statements , just not in the sample code. Just to keep it simple.
When i call the endpoint: /savesomething
I should see “invalid API” (if its invalid ofcource). But even if its invalid, it still saved the data from the /savesomething functions.
Its something with the middleware function that doesnt work properly. it doesnt stop executing the rest and still saves data even though the APIkey is invalid.
The reason is, your current middleware is implemented as an outgoing middleware because you first invoke the handle method, and then it does the API-Key checks. This means, your endpoint will be executed before the middleware checks the credentials. To change this order, just need invoke the handle method only when the user / API-key is valid.
You need to check for a valid API-key first. If the key is valid, invoke the handle method. If the key is not valid, return a 401 response or throw a HttpForbiddenException.
throw new \Slim\Exception\HttpForbiddenException();
401 Unauthorized:
If the request already included Authorization credentials, then the 401 response indicates that authorization has been refused for those credentials.
403 Forbidden:
The server understood the request, but is refusing to fulfill it.
From your use case, it appears that the user is not authenticated. I would return 401.
My API key check middleware here , just to share the code
// Check if API key is valid before running the app
$app->add(function (Request $request, RequestHandler $handler) {
// Retrieve the API get from body (Raw json)
// Example: {"apikey": "XXXX-XXXX-XXXX-XXXX"}
$apikey = $request->getParam("apikey") ?? ""; // Api key provided. If none provided set it to empty.
// Ignore endpoints in this array
$ignoredEndpoints = array("/service/client/wordpress/createsitekey");
$endpoint = $request->getUri()->getPath();
// IF endpoint requested is in array, skip the API key check.
if(in_array($endpoint, $ignoredEndpoints)) {
$response = $handler->handle($request);
$response->getBody();
return $response;
}
// Check if the API key is empty,before connecting to the database.
if($apikey == "") {
throw new \Slim\Exception\HttpForbiddenException($request, "Missing API key...");
}
// Connect to the database
$db = new DB();
$conn = $db->connect();
// Check the API key against users
$stmt = $conn->prepare("SELECT * FROM users WHERE apikey = :apikey LIMIT 1");
$stmt->bindParam(":apikey", $apikey);
$result = $stmt->execute();
$rowCount = $stmt->rowCount();
$user = $stmt->fetch(PDO::FETCH_OBJ);
// Close db connection, we got the data
$db = null;
// Check if this APi key auctually exists
if($rowCount != 1) {
throw new \Slim\Exception\HttpForbiddenException($request, "APi key invalid...");
}
// No errors was found, return the app responses
$response = $handler->handle($request);
$response->getBody();
return $response;
});
To transform the Exception into a JSON response, you can add a handler to the Slim ErrorMiddleware or you implement a custom Middleware that catches this specific Exception and renders the Exception into (JSON) response.