On the backend a custom token is generated via firebase's admin SDK thusly:
router.use('/get-token', (req, res) => {
var uid = "big-secret";
admin.auth().createCustomToken(uid)
.then(function(customToken) {
res.json({
instanceID: customToken
});
})
.catch(function(error) {
console.log("Error creating custom token:", error);
});
});
The client frontend app then picks up the customToken and with it makes a request back to the backend to verify:
const fbPrivateKey = serviceAccount.private_key;
const key = new NodeRSA(fbPrivateKey).exportKey('pkcs8-public-pem');
router.get('/verifyIdToken', cors(), (req, res) => {
jwt.verify(req.headers.authorization.split('Bearer ')[1], key, { algorithms: ['RS256'] }, function(err, decoded) {
console.log('err', err);
console.log('decoded', decoded);
});
This always errors with the message: JsonWebTokenError: invalid signature
Does this need signing? If anyone could explain this or has any pointers?
UPDATE:
When running req.headers.authorization.split('Bearer ')[1]
through jwt.io is says that the signature is invalid, but then I enter my private key (key
) and it validates.
Am I getting the method calls incorrect or passing the wrong arguments into jwt.verify()
?
To do so securely, after a successful sign-in, send the user's ID token to your server using HTTPS. Then, on the server, verify the integrity and authenticity of the ID token and retrieve the uid from it. You can use the uid transmitted in this way to securely identify the currently signed-in user on your server.
Because Firebase ID tokens are stateless JWTs, you can determine a token has been revoked only by requesting the token's status from the Firebase Authentication backend. For this reason, performing this check on your server is an expensive operation, requiring an extra network round trip.
It looks like you're calling verifyIdToken
with a custom token. That's not going to work. verifyIdToken
only accepts "ID tokens". To obtain an ID token from a custom token first call signInWithCustomToken()
. Then call getToken()
on the signed in user instance.
If you dont want to use signInWithCustomToken() this is the correct way to do it
const publicKey = new NodeRSA().importKey(serviceAccount.private_key, "pkcs8-private-pem").exportKey("pkcs8-public-pem")
jwt.verify(token, publicKey, {
algorithms: ["RS256"]
}, (err, decoded) => {
if (err) {
# send some error response
res.status(400).json({
status: 0,
message: "Token is invalid!"
})
} else {
# send some valid response
res.status(200).json({
status: 1,
message: "Token is valid for uid " + decoded.uid
})
}
})
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With