kreait / firebase-tokens-php

A PHP library to work with Firebase tokens
MIT License
223 stars 33 forks source link

clarification about how token verification works #22

Closed rtpHarry closed 4 years ago

rtpHarry commented 4 years ago

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?

jeromegamez commented 4 years ago

It's exactly how you described - without a cache, each call to your PHP backend will result in an additional call to the Google Servers to fetch the public keys (they are used to check the JWT signature of your incoming tokens).

I don't know if Google minds, but in any case, it will slow down the process a bit, so if you can, using the verifier with a cache would definitely be a good idea.

If you verify multiple tokens during one request/PHP-process, the tokens will be fetched only once for all verifications, but only if you use the same instance of the verifier.

I see in your code that you are creating a new instance of the IdTokenVerifier each time you verify a token. Without knowing your project, of course, I would probably instantiate it in the constructor and save it in a class property to use it later with $this->verifier->verifyIdToken($token); ... this would at least provide the "re-use it during a request/process" case.

Are you using the verifier with Laravel or Symfony? I am quite confident that it would be quite easy™ to use the framework's cache components with the verifier 🤔💪

In any case, let me know if I can help, and if you'd like, join our Community Discord at https://discord.gg/nbgVfty for a more interactive exchange of thoughts 😅

rtpHarry commented 4 years ago

Thanks for the prompt reply, I'll take another read through of this tomorrow when I'm at my desk.

It has definitely clarified some things. I was actually creating that token verifier twice per request so I'll move that over to a class property.

The api is based on slim framework v4.

rtpHarry commented 4 years ago

Thanks, just realised I never came back to this one. Your tips were a big help.