Verify JWT from Google Chat POST request

2019-08-10 04:33发布

问题:

I have a bot in NodeJS connected to Google Chat using HTTPs endpoints. I am using express to receive requests. I need to verify that all requests come from Google, and want to do this using the Bearer Token that Google Sends with requests.

My problem is that I am struggling to find a way to verify the tokens.

I have captured the token and tried a GET reuqes to https://oauth2.googleapis.com/tokeninfo?id_token=ey... (where ey... is the token start).

Which returns:

    "error": "invalid_token",
    "error_description": "Invalid Value"
}

I have tried what Google recommends:

var token = req.headers.authorization.split(/[ ]+/);
client.verifyIdToken({
    idToken: token[1],
    audience: JSON.parse(process.env.valid_client_ids)
}).then((ticket) => {
    gchatHandler.handleGChat(req.body, res);
}).catch(console.error);

And get the following error:

Error: No pem found for envelope: {"alg":"RS256","kid":"d...1","typ":"JWT"}

Any idea where I should head from here?

Edit: https://www.googleapis.com/service_accounts/v1/metadata/x509/chat@system.gserviceaccount.com found this, investigating how to use it. The kid matches the one I get.

回答1:

Worked it out, eventually.

You need to hit: https://www.googleapis.com/service_accounts/v1/metadata/x509/chat@system.gserviceaccount.com to get a JSON file containing the keys linked to their KIDs.

Then when a request arrives, use jsonwebtoken (NPM) to decode the token and extract the KID from the header.

Use the KID to find the matching public key in the response from the website above, then use the verify function to make sure the token matches the public key.

You also need to pass the audience and issuer options to verify, to validate that it is your particular service account hitting the bot.