Hi all, I am working on a new project which use Firebase and would I would like to integrate it with my Slim REST API. I cloned a Slim 4 skeleton add it my code in the middleware then when I make my calls with X-Authorization Bearer but get the following error:
slim.WARNING: OpenSSL error: error:0906D06C:PEM routines:PEM_read_bio:no start line [“eyJhbGciOiJSUzI1NiIsIm…”]
“description”: "ERROR: openssl_verify(): supplied key param cannot be coerced into a public key on line 243 in file.
Any ideas what might be wrong? the secret and token used are checked in a simple php file and are valid.
This is my middleware.php
<?php
declare(strict_types=1);
use Psr\Http\Message\ServerRequestInterface as Request;
use Psr\Http\Server\RequestHandlerInterface as RequestHandler;
use Slim\Psr7\Response;
use App\Application\Middleware\SessionMiddleware;
use App\Application\Middleware\CorsMiddleware;
use Slim\App;
//Extra for auth
use Tuupola\Middleware\HttpBasicAuthentication;
use \Firebase\JWT\JWT;
use Monolog\Logger;
use Monolog\Handler\RotatingFileHandler;
return function (App $app) {
$app->add(CorsMiddleware::class);
$container = $app->getContainer();
$rawPublicKeys = file_get_contents('https://www.googleapis.com/robot/v1/metadata/x509/securetoken@system.gserviceaccount.com');
$keys = json_decode($rawPublicKeys, true);
$keyKidsArray= array_keys($keys);
$pKeysArray = array_values($keys);
$secrets = $keyKidsArray[0] . ':' . $pKeysArray[0] . ',' . $keyKidsArray[1] . ':' . $pKeysArray[1];
$logger = new Logger("slim");
$rotating = new RotatingFileHandler(__DIR__ . "/logs/slim.log", 0, Logger::DEBUG);
$logger->pushHandler($rotating);
echo $secrets;
$app->add(new Tuupola\Middleware\JwtAuthentication([
"ignore" => ["/api/records/countries","/faqs"],
"algorithm" => ["RS256"],
"header" => "X-Authorization",
"regexp" => "/Bearer\s+(.*)$/i",
"logger" => $logger,
"secret" => $secrets,
"secure" => false,
"error" => function ($response, $arguments) {
$data["status"] = "error";
$data["message"] = $arguments["message"];
return $response
->withHeader("Content-Type", "application/json")
->getBody()->write(json_encode($data, JSON_UNESCAPED_SLASHES | JSON_PRETTY_PRINT));
}
]));
};
What are you trying to achieve by downloading the public keys for each API request from the Google server?
According to Tuupola’s documentation, the secret is just a fixed string.
For simplicity’s sake examples show secret hardcoded in code. In real life you should store it somewhere else. Good option is environment variable. You can use dotenv or something similar for development. Examples assume you are using Slim Framework.
using the secrets from Google server for firebase, you can use the firebase authentication generated JWT and validate it in your server. So the user flow is: Users login with firebase, gets token, make a request to my slim api (get pois with X-Authorization Bearer TOKEN_FROM_FIREBASE), midleware checks token against keys and authorizes user in my API.
Although I have managed to get it working with other systems (check for example this ), it looks like the issue here is Firebase/php-jwt, which is used by Tuupola JwtAuthentication and not processing the keys as should.
Can you suggest another lib or even another way to approach this?
EDIT:
Working further with it, i am now 100% that Tuupola\JwtAuthentication is not the issue. Editing line 243 in Firebase/php-jwt/JWT.php (//$success = openssl_verify($msg, $signature, $key, $algorithm); ) allows the system to authenticate correctly and get the expected behavior.
Ok so after further work with it, it looks like the firebase/php-jwt does all the job of splitting the keys to KID, secret etc internally and I didnt have to provide them on my own. After passing the $keys as a secret for the middleware, everything worked as should.