kreait / firebase-tokens-php Goto Github PK
View Code? Open in Web Editor NEWA PHP library to work with Firebase tokens
License: MIT License
A PHP library to work with Firebase tokens
License: MIT License
When trying out your code, as per the example in the readme. I am getting an error as below:
[Sun Jun 11 02:14:08.042454 2017] [:error] [pid 1813] [client 192.168.0.118:63309] PHP Fatal error: Uncaught Error: The "Generator" class is reserved for internal use and cannot be manually instantiated in /var/www/html/firebase/generate_token.php:10\nStack trace:\n#0 {main}\n thrown in /var/www/html/firebase/generate_token.php on line 10, referer: http://192.168.0.105/firebase/
My sample code is given below:
<?php
use Firebase\Auth\Token\Handler;
$projectId = 'test'; //replaced
$clientEmail = '[email protected]'; //replaced
$generator = new Generator($clientEmail, $privateKey);
$uid = '1';
$claims = ['email' => '[email protected]',
'username' => 'some1'
];
$token = $generator->createCustomToken($uid, $claims);
// Returns a Lcobucci\JWT\Token instance
echo $token; // "eyJ0eXAiOiJKV1..."
?>
Auth Emulator Support is currently only tested implicitly by the Firebase Admin SDK, but not directly here (just locally on my computer).
The Firebase Admin SDK is able to create users but can't be used here (recursive dependency)
Is it so hard to type include('domain/generator.php')
and so on to include the required files, that you force developers to install the Composer extension to save a few bytes?
Honestly I never understood that policy of adding unnecessary extensions that only create problems when trying to setup a new server or migrate an existing one. Please reconsider it in your future projects if you want to make them ready to use without headaches and complications for fellow developers, thanks.
After updating dependencies and getting a new peer-dependency of lcobucci/jwt my application started throwing "InvalidKeyProvided with message 'Key cannot be empty'" exception. After digging through the source code it seems to have been added on purpose, and then finding this: lcobucci/jwt#877 confirms it. Which means this package needs to be updated accordingly I guess?
Hi there,
I was wondering if you know of a way to use the cache ie
use Symfony\Component\Cache\Simple\FilesystemCache;
$cache = new FilesystemCache();
with the Laravel wrapper which is built on top of Symfony?
I tried to send do it like this but got an error:
$verifier = IdTokenVerifier::createWithProjectIdAndCache($projectId,
\Illuminate\Support\Facades\Cache::class);
Error: "The cache must implement Psr\\SimpleCache\\CacheInterface or Psr\\Cache\\CacheItemPoolInterface
Include https://session.firebase.google.com/{$this->projectId}
to https://github.com/kreait/firebase-tokens-php/blob/main/src/JWT/Action/VerifyIdToken/WithLcobucciJWT.php#L71
Include https://www.googleapis.com/identitytoolkit/v3/relyingparty/publicKeys
to https://github.com/kreait/firebase-tokens-php/blob/main/src/JWT/Action/FetchGooglePublicKeys.php#L12
OWASP has a bunch of recommendations for JWT security to prevent:
It would be great if these were configurable options on the Firebase Authentication of this library that we could enable and configure on an as-needs basis.
For example, a potential implementation of the Token Sidejacking validation would be for
src/JWT/Action/VerifyIdToken/WithLcobucciJWT.php handle()
function to add an additional validator to validate .withClaim("userFingerprint", userFingerprintHash)
.
As this is not a core function of the encoding/decoding of the token (which would imply updating the Lcobucci/JWT library), I think these changes live in this library.
I am using the bellow snippet to generate custom tokens for clients who are using my Flutter mobile app.
$privateKey = json_decode(file_get_contents( storage_path() . '/app/google-services.json'), true)['private_key'];
$generator = CustomTokenGenerator::withClientEmailAndPrivateKey($clientEmail, $privateKey);
$token = $generator->createCustomToken('uid', ['first_claim' => 'first_value' /* ... */]);
return json_encode(["status_code" => "200", "token" => $token->toString() ]);
When I am reusing the $token->toString()
in my FirebaseAuth.instance.signInWithCustomToken ( token: '${httpResponse['token']}')
I get firebase error “FirebaseAuthInvalidCredentialsException: The custom token format is incorrect.” .
According to firebase group it is a generic error message for if the maximum expiration time is more than one hour
https://groups.google.com/forum/#!msg/firebase-talk/tYRfde4nwBY/yAn5I_spBQAJ . Does the CustomTokenGenerator::withClientEmailAndPrivateKey take any maximum expiration time parameter?
Also I wonder if the $token->toString() is the correct value which I should return from my server to my mobile app ?
Thank you for you troubles.
It seems that the library fetches Firebase public keys from https://www.googleapis.com/robot/v1/metadata/x509/[email protected]
URL for every request. If I'm missing something please correct me.
If this is the case, wouldn't it be better to cache public keys on the first run and try to re-fetch them only for a cache-miss scenario? This way a huge HTTP overhead would be avoided for the tokens with the known same public keys.
What do you think of this proposal?
I am trying to verify the firebase token but sometimes, it is throwing token issued at future timestamp error, as in the following exception:
This token has been issued in the future at 2019-06-07T08:43:57+00:00, is your system time correct? {"exception":"[object] (Firebase\\Auth\\Token\\Exception\\IssuedInTheFuture(code: 0): This token has been issued in the future at 2019-06-07T08:43:57+00:00, is your system time correct? at /var/www/html/vendor/kreait/firebase-tokens/src/Verifier.php:95)
I debugged the the code, and I saw the following rows are the problem:
private function verifyAuthTime(Token $token)
{
...
if ($token->getClaim('auth_time') > time()) {
throw new InvalidToken($token, "The user's authentication time must be in the past");
}
}
The difference is between the auth_time and time() only a few seconds.
Hello!
I am trying to upgrade to version 2.2.0 of this package from version 1.16.1 but I am getting the following error:
auth::createCustomToken(): Return value must be of type Lcobucci\JWT\UnencryptedToken, Kreait\Firebase\JWT\Token returned
This is what my code calling the method looks like:
$customToken = Firebase::project(applicationId())->auth()->createCustomToken($identifier, [ 'email' => $model->email, ]);
This library is up and running on my little api, thanks.
For each request I am passing in the Auth... bearer...
header.
On the api side im doing this using middleware on every request:
/**
* Parse token.
*
* @param string $token The JWT
*
* @return Token The parsed token
*/
public function createParsedToken(string $token): Token
{
$verifier = IdTokenVerifier::createWithProjectId($this->projectId);
return $verifier->verifyIdToken($token);
}
/**
* Validate the access token.
*
* @param string $accessToken The JWT
*
* @return bool The status
*/
public function validateToken(string $accessToken): bool
{
$token = null;
// create + validate
try {
$token = $this->createParsedToken($accessToken);
} catch (IdTokenVerificationFailed $e) {
// signature is not valid
return false;
}
// user must have verified email to proceed
if($token->payload()["email_verified"] === false) {
return false;
}
return true;
}
I just have the default in memory cache setup.
I'm worried about what this code is actually doing.
So what is actually happening with the code? Is this correct:
If the keys are cached then does it need to call out to Firebase Auth to validate the token or is it all done server-side?
One of the request is going to be polled every few seconds, and I have this concern that I've misunderstood what I'm doing and I'm buzzing the firebase servers every 2 seconds with verification requests?
Maybe it's just me not knowing enough PHP but it was tricky to know what the reply was when my api was running on a server. I had to write a custom api route to just dump it out (and figure out if I should have been using headers()
or payload()
)
An example of the payload()
array in the documentation would have helped eg:
{
"iss": "https://securetoken.google.com/{{PROJECTID}}",
"aud": "{{PROJECTID}}",
"auth_time": 1578755578,
"user_id": "c7LXiEYnbPqqbr8OZcNeBcI2PIi1",
"sub": "c7LXiEYnbPqqbr8OZcNeBcI2PIi1",
"iat": 1580038499,
"exp": 1580042099,
"email": "[email protected]",
"email_verified": true,
"firebase": {
"identities": {
"email": [
"[email protected]"
]
},
"sign_in_provider": "password"
}
}
Hello, thanks for putting this and your other package together. I notice there is no method to sign back into Firebase with a custom token. The docs show an example using the method signInWithCustomToken
and I was wondering if there is a way to implement this?
I have a Laravel backend where our authentication is taking place. I am trying to build a way for our mobile app to authenticate to the Laravel app and have the Laravel app generate a Firebase token the mobile app can use to access the real time db/Firestore. Is this something that can be accomplished?
I have been able to generate the token using this code:
$serviceAccount = ServiceAccount::fromJsonFile(DIR . '/firebase-adminsdk-baomg-ed357f2f41.json');
$firebase = (new Factory)
->withServiceAccount($serviceAccount)
->create();
$auth = $firebase->getAuth();
$uid = 'AE0xzvmtu7Ox85S9jYJ0zt7Y8yH2';
$additionalClaims = [
'premiumAccount' => true,
];
$customToken = $firebase->getAuth()->createCustomToken($uid, $additionalClaims);
$customTokenString = (string) $customToken;
``
but when I try to authenticate using this code:
try {
$verifiedIdToken = $firebase->getAuth()->verifyIdToken($customTokenString);
} catch (InvalidToken $e) {
echo $e->getMessage();
}
$uid = $verifiedIdToken->getClaim('sub');
$user = $firebase->getAuth()->getUser($uid);
dd($user);
I am gettting:
message": "The header \"kid\" is missing.",
From what I have read, it seems the verifyIdToken
method is used to verify a valid token already on Firebase and I am looking for a way to validate the custom token generated by my Laravel backend auth.
Thanks again, I look forward to any advice or suggestions you may have.
{ "message": "Unknown key", "error": "A key with ID \"The token with ID \"%s\" is unknown.\" could not be found." }
I get that error after declaring $verifier = new Verifier($projectId);
Looks like it expects to get the key from some header value or a declared value when the object in created. public function __construct(string $projectId, KeyStore $keys = null, Signer $signer = null)
Would you happen to have a better working code example?
Fatal error: Uncaught Error: Class 'IdTokenVerifier' not found in public_html/session.php:18 Stack trace: #0 {main} thrown in
used composer require kreait/firebase-tokens
for install it
and using your example
<?php
use Kreait\Firebase\JWT\Error\IdTokenVerificationFailed;
use Kreait\Firebase\JWT\IdTokenVerifier;
$projectId = '...';
$idToken = 'eyJhb...'; // An ID token given to your backend by a Client application
$verifier = IdTokenVerifier::createWithProjectId($projectId);
try {
$token = $verifier->verifyIdToken($idToken);
} catch (IdTokenVerificationFailed $e) {
echo $e->getMessage();
// Example Output:
// The value 'eyJhb...' is not a verified ID token:
// - The token is expired.
exit;
}
try {
$token = $verifier->verifyIdTokenWithLeeway($idToken, $leewayInSeconds = 10000000);
} catch (IdTokenVerificationFailed $e) {
print $e->getMessage();
exit;
}
Need to upgrade dependencies to lcobucci/jwt:^4.0, otherwise library can be incompatible with php 8
Do you have a schedule update of firebase/php-jwt in major 1.* in the next future ?
Describe the bug
I ran composer update, "lcobucci/jwt" has been updated from 3.3.3 to 3.4.0, then authentication doesn't work anymore
To Reproduce
install fresh or update current install and try to verify a token
app('firebase.auth')->verifyIdToken($request->get("jwt"));
Expected behavior
it should auth correctly
Environment (please complete the following information):
Additional context
Error message
The token has an invalid signature: Implicit conversion of keys from strings is deprecated. Please use InMemory or LocalFileReference classes.
Stacktrace
\vendor\kreait\firebase-tokens\src\Firebase\Auth\Token\Verifier.php:145
\vendor\kreait\firebase-tokens\src\Firebase\Auth\Token\Verifier.php:68
\vendor\kreait\firebase-php\src\Firebase\Auth\IdTokenVerifier.php:53
\vendor\kreait\firebase-php\src\Firebase\Auth.php:581
Hi, would you mind to have a sample?
I don't know how to load the privateKey
. How?
Is clientEmail
my admin email or my app user email?
Hello,
I faced an issue with tokens being randomly rejected due to IAT being in future. I figured out my hosting provider time is fraction of second behind from firebase server and this caused random failures (depending on user connection) of IAT verification because token was sometime issued practically at the same time as checked on server side.
Temporary, I disabled IAT verification but it is obvious security hole. I was thinking - would you be interested in adding possibility to enable/disable verifications with flags or some config? I can imagine for example some sort of offset for IAT verification. Developers could add few secs tolerance so 1-2 seconds "in future" would not cause an issue.
Hello, I'm trying to get the uid from the verified Firebase token, but I'm unable to use the 'getClaims('sub')' method. I'm using the same exact code under the 'Verify an ID token' heading, just adding the token from Firebase, but when I add '$token->getClaims('sub')' to try get retrieve the uid, I get the error below. I'm fairly new to implementing libraries and I'm just unsure how to retrieve the sub-claim. Also, I'm not using Firebase Admin SDK as my backend.
Please help, thanks!
{
"require": {
"kreait/firebase-tokens": "^4.2",
"kreait/firebase-php": "^7.6",
"lcobucci/jwt": "^5.1",
"firebase/php-jwt": "^6.9"
}
}
composer 2.6.5 Composer package
composer-plugin-api 2.6.0 The Composer Plugin API
composer-runtime-api 2.2.2 The Composer Runtime API
ext-bcmath 8.2.4 The bcmath PHP extension
ext-bz2 8.2.4 The bz2 PHP extension
ext-calendar 8.2.4 The calendar PHP extension
ext-ctype 8.2.4 The ctype PHP extension
ext-curl 8.2.4 The curl PHP extension
ext-date 8.2.4 The date PHP extension
ext-dom 20031129 The dom PHP extension
ext-exif 8.2.4 The exif PHP extension
ext-fileinfo 8.2.4 The fileinfo PHP extension
ext-filter 8.2.4 The filter PHP extension
ext-ftp 8.2.4 The ftp PHP extension
ext-gettext 8.2.4 The gettext PHP extension
ext-hash 8.2.4 The hash PHP extension
ext-iconv 8.2.4 The iconv PHP extension
ext-json 8.2.4 The json PHP extension
ext-libxml 8.2.4 The libxml PHP extension
ext-mbstring 8.2.4 The mbstring PHP extension
ext-mysqli 8.2.4 The mysqli PHP extension
ext-mysqlnd 0 The mysqlnd PHP extension (actual version: mysqlnd 8.2.4)
ext-openssl 8.2.4 The openssl PHP extension
ext-pcre 8.2.4 The pcre PHP extension
ext-pdo 8.2.4 The PDO PHP extension
ext-pdo_mysql 8.2.4 The pdo_mysql PHP extension
ext-pdo_sqlite 8.2.4 The pdo_sqlite PHP extension
ext-phar 8.2.4 The Phar PHP extension
ext-random 8.2.4 The random PHP extension
ext-readline 8.2.4 The readline PHP extension
ext-reflection 8.2.4 The Reflection PHP extension
ext-session 8.2.4 The session PHP extension
ext-simplexml 8.2.4 The SimpleXML PHP extension
ext-sodium 8.2.4 The sodium PHP extension
ext-spl 8.2.4 The SPL PHP extension
ext-tokenizer 8.2.4 The tokenizer PHP extension
ext-xml 8.2.4 The xml PHP extension
ext-xmlreader 8.2.4 The xmlreader PHP extension
ext-xmlwriter 8.2.4 The xmlwriter PHP extension
ext-zip 1.21.1 The zip PHP extension
ext-zlib 8.2.4 The zlib PHP extension
lib-bz2 1.0.8 The bz2 library
lib-curl 7.85.0 The curl library
lib-curl-libssh2 1.10.0 curl libssh2 version
lib-curl-openssl 3.0.8 curl OpenSSL version (3.0.8)
lib-curl-zlib 1.2.12 curl zlib version
lib-date-timelib 2022.05 date timelib version
lib-date-zoneinfo 2022.7 zoneinfo ("Olson") database for date
lib-fileinfo-libmagic 540 fileinfo libmagic version
lib-iconv 1.16 The iconv library
lib-libsodium 1.0.18 The libsodium library
lib-libxml 2.10.3 libxml library version
lib-mbstring-libmbfl 1.3.2 mbstring libmbfl version
lib-mbstring-oniguruma 6.9.8 mbstring oniguruma version
lib-openssl 3.0.8 OpenSSL 3.0.8 7 Feb 2023
lib-pcre 10.40 The pcre library
lib-pcre-unicode 14.0.0 PCRE Unicode version support
lib-pdo_sqlite-sqlite 3.39.2 The pdo_sqlite-sqlite library
lib-zip-libzip 1.7.1 The zip-libzip library
lib-zlib 1.2.12 The zlib library
php 8.2.4 The PHP interpreter
php-64bit 8.2.4 The PHP interpreter, 64bit
php-ipv6 8.2.4 The PHP interpreter, with IPv6 support
php-zts 8.2.4 The PHP interpreter, with Zend Thread Safety
<?php
require __DIR__ . '/vendor/autoload.php';
use Kreait\Firebase\JWT\Error\IdTokenVerificationFailed;
use Kreait\Firebase\JWT\IdTokenVerifier;
$projectID = '...'; // firebase project id
$verifier = IdTokenVerifier::createWithProjectId($projectID);
$userIdToken = 'eyJh...';
try {
$token = $verifier->verifyIdToken($userIdToken);
$uid = $token->getClaims('sub');
echo "valid token";
} catch (IdTokenVerificationFailed $e) {
echo $e->getMessage();
}
?>
-
No response
Cache results from the Google Secure Token Store
In order to verify ID tokens, the verifier makes a call to fetch Firebase's currently available public keys.
The keys are cached in memory by default.
How do I clear this cache? I created a new project and it is still looking for the old project name.
Firebase verifyIdToken fails with exception as Firebase\Auth\Token\Exception\UnknownKey
Stacktrace
A key with ID "3494b1e786cdad092e423766bbe37f54ed87b22d" could not be found. {"exception":"[object] (Firebase\\Auth\\Token\\Exception\\UnknownKey(code: 0): A key with ID \"3494b1e786cdad092e423766bbe37f54ed87b22d\" could not be found. at /home/fgx3uhiothty/public_html/vendor/kreait/firebase-tokens/src/Verifier.php:132)
Maybe provide links to the Firebase SDK?
Also, the examples on the main page fail. How do we make them work?
Hi, I just installed the lib with composer and I have a problem with the lib "Lcobucci/JWT".
Error:
Fatal error: Uncaught Error: Class 'Lcobucci\JWT\Signer\Key\InMemory' not found in /wp-content/plugins/myplugin/Firebase/vendor/kreait/firebase-tokens/src/Firebase/Auth/Token/Generator.php on line 38
My composer
"minimum-stability": "dev",
"require": {
"kreait/firebase-php": "^5.19",
"kreait/firebase-tokens": "^1.15"
}
My php file
use Kreait\Firebase\Factory;
use Kreait\Firebase\Auth;
$factory = (new Factory)->withServiceAccount(__DIR__ . '/google-service.json);
$auth = $factory->createAuth();
Do you know what the error is, please ?
In src/JWT/action/CreateCustomToken.php
MAXIMUM_TTL is set to PHT1H which expires in an hour i want it P1D
Even your function createCustomToken doens't let me go beyond 1 Hour can you remove the validation or provide a solution.
Thanks
Hey, first of all great library, I used this library for developing a Laravel package for authenticating firebase token. would you be kind to tell me what is the purpose of HttpKeyStore.php ? thankyou
I think Google updated the 'iss' claim from https://securetoken.google.com/[projectId] to https://accounts.google.com. Therefore, verifyIdToken function fails with message: "This token has an invalid issuer". Am I doing something wrong?
I can CreateSessionCookie but unable to verify the output string
Hello,
Why final class Handler implements Domain\Generator, Domain\Verifier
class is final ?
I'd like to extend it to add a method to only verify if the token is expired ...
Thank you
Key with ID "%s" not found.
I Have found one more solution to this issue is other than what people have suggested is
to add this one more URL which has the keys that were used to sign idTokens coming from kotlin android app and ios app
kreait/ firebase-token/src/Firebase/Auth/Token/HttpKeyStore
const KEYS_URL_1 = 'https://www.googleapis.com/robot/v1/metadata/x509/[email protected]';
const KEYS_URL_2 = 'https://www.googleapis.com/oauth2/v1/certs';
then the keys array will have all 4 keys (2 web keys and the other 2 keys as well)
Can we have this added in the coming version on kreait/firebase-tokens-php
In the advanced usage / cache section the sentence is not finished:
If you want to cache the public keys more effectively, you can use an implementation of psr/simple-cache or psr/cache to wrap the
It looks like composer.json
was updated for Guzzle 7 stable, but a new release hasn't been tagged.
Laravel 8 now requires Guzzle 7.0 so this prevents it from being installed alongside.
Could we please get a new tagged release?
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.