3

I have a firebase account where I manually create the users who will be abled to use my site (sign up is not public, but it is not relevant to this inquiry)

In the login page, the authentication is through javascript.
Once the user enters their mail and password the corresponding function is executed, I get the token and I send it to my PHP server via url redirection. Something like this:

firebase.auth().signInWithEmailAndPassword(inputemail, inputpassw)
    .then( function(user) {

        myEmail = user.email;
        myUid = user.uid;

        user.getIdToken()
            .then( function(token){
                myToken = token;

                location.href = "http://www.example.com/verify?email="+myEmail+"&token="+myToken+"&uid="+myUid;

            });

    }, function (error) {
       ...
    }); 

Then, on my server I will have the mail, the uid, and the token.
So, my question is:
How do I verify that the token is valid? It is impossible?
I know the token is encrypted, but the key is public... so anyone could make a valid token!
I mean, for instance, I have an expired token, I can decode it, change the expiration time, encode it again and gain access to my server without knowing any password

Is there something I'm missing?

Apparently I can not verify the token via REST.
What alternative do I have?

Leonardo Javier
  • 89
  • 1
  • 2
  • 11
  • There is no need to call the Firebase servers, to verify the ID token. All the information is in the token itself and it can be decoded with the service credentials. See https://stackoverflow.com/questions/42084299/firebase-token-verification-in-php and https://stackoverflow.com/questions/37634305/firebase-token-verification and https://packagist.org/packages/firebase/php-jwt – Frank van Puffelen May 29 '17 at 19:25
  • did you read the full question? – Leonardo Javier May 29 '17 at 19:34
  • Apparently not. Then again: the links I gave provide the exact answer to your question's title, verifying the JWT in PHP. If you're asking why this is a secure approach, I'd recommend updating the title to reflect that. It's a valid question, just different from what your title currently asks. The answer is btw that minting a JWT requires that you have access to the credentials of the project. Since those are private, only someone with access to them can mint valid tokens. – Frank van Puffelen May 29 '17 at 19:38
  • I don't know what "mint JWT" is... neither what do you mean with the "credentials of the project"... I use the Firebase console...is it there? – Leonardo Javier May 29 '17 at 22:23
  • See https://firebase.google.com/docs/auth/admin/verify-id-tokens#verify_id_tokens_using_a_third-party_jwt_library for more info on how to verify Firebase ID tokens using a third party JWT library. – Frank van Puffelen May 30 '17 at 01:43

1 Answers1

3

From the Firebase Documentation:

The Firebase Admin SDK has a built-in method for verifying and decoding ID tokens. If the provided ID token has the correct format, is not expired, and is properly signed, the method returns the decoded ID token. You can grab the uid of the user or device from the decoded token.

So, you do not need to worry about someone trying to generate fake tokens.

To verify the token in PHP, as described in the docs Firebase Admin SDK for PHP

Minimal code for verifying the token:

use Kreait\Firebase;
use Firebase\Auth\Token\Exception\InvalidToken;

//create Firebase factory object
//$firebase = (new Firebase\Factory())->create();

//get a token from client 
//$idTokenString = 'eyJhbGciOiJSUzI1...';

try {
    $verifiedIdToken = $firebase->getAuth()->verifyIdToken($idTokenString);
} catch (InvalidToken $e) {
    echo $e->getMessage();
}

$uid = $verifiedIdToken->getClaim('sub');
$user = $firebase->getAuth()->getUser($uid);
echo $user; 
Mann
  • 307
  • 2
  • 14
  • I repeat what I said: "if I found an expired token, I can decode it, change the expiration time, encode it again and gain access to my server without knowing any password." I fact, that was what I did and it worked. So I think the only solution for now is to generate my own tokens – Leonardo Javier Jun 30 '17 at 18:28
  • 1
    Again, you can decode the token with the public key but you cannot encode it with the public key. If you encode it with the public key then token verification will fail on your server. I assume it worked in your case because you have both the public and private keys. But rest of the world do not have your private key. If you still think you can do it then write an email to Google, you outsmart them! – Mann Jul 03 '17 at 12:39
  • Getting Call to undefined method Kreait\Firebase::getTokenHandler() – goyote Jan 04 '19 at 03:29
  • Thanks for pointing that out, API was updated in the meantime. I have adjusted my code. Should work now! – Mann Jan 04 '19 at 13:49