node.js - firebase-admin (nodejs) 无法验证身份验证令牌 (JWT)
问题描述
我正在使用 firebase-admin (node-js) 来验证 Auth 令牌。
我正在使用 firebase docs 提供的示例
我试图解码我正在使用的令牌,它可以工作
{
"iss": "https://securetoken.google.com/xxxxxx",
"aud": "xxxxxxx",
"auth_time": 1557423742,
"user_id": "xxxxxxxxxxxxx",
"sub": "xxxxxxxxx",
"iat": 1557427419,
"exp": 1557431019,
"email": "xxxxx@gmail.com",
"email_verified": false,
"firebase": {
"identities": {
"email": [
"xxxxx@gmail.com"
]
},
"sign_in_provider": "password"
}
}
我尝试在 firebase-admin 代码中记录令牌
lib/auth/token-verifier.js
FirebaseTokenVerifier.prototype.verifyJWT = function (jwtToken) {
var _this = this;
console.log(`"${jwtToken}"`); // HERE
if (!validator.isString(jwtToken)) {
throw new error_1.FirebaseAuthError(error_1.AuthClientErrorCode.INVALID_ARGUMENT, "First argument to " + this.tokenInfo.verifyApiName + " must be a " + this.tokenInfo.jwtName + " string.");
}
if (!validator.isNonEmptyString(this.projectId)) {
throw new error_1.FirebaseAuthError(error_1.AuthClientErrorCode.INVALID_CREDENTIAL, "Must initialize app with a cert credential or set your Firebase project ID as the " +
("GOOGLE_CLOUD_PROJECT environment variable to call " + this.tokenInfo.verifyApiName + "."));
}
var fullDecodedToken = jwt.decode(jwtToken, {
complete: true,
});
var header = fullDecodedToken && fullDecodedToken.header;
var payload = fullDecodedToken && fullDecodedToken.payload;
var projectIdMatchMessage = " Make sure the " + this.tokenInfo.shortName + " comes from the same " +
"Firebase project as the service account used to authenticate this SDK.";
var verifyJwtTokenDocsMessage = " See " + this.tokenInfo.url + " " +
("for details on how to retrieve " + this.shortNameArticle + " " + this.tokenInfo.shortName + ".");
var errorMessage;
if (!fullDecodedToken) {
errorMessage = "Decoding " + this.tokenInfo.jwtName + " failed. Make sure you passed the entire string JWT " +
("which represents " + this.shortNameArticle + " " + this.tokenInfo.shortName + ".") + verifyJwtTokenDocsMessage;
}
else if (typeof header.kid === 'undefined') {
var isCustomToken = (payload.aud === FIREBASE_AUDIENCE);
var isLegacyCustomToken = (header.alg === 'HS256' && payload.v === 0 && 'd' in payload && 'uid' in payload.d);
if (isCustomToken) {
errorMessage = this.tokenInfo.verifyApiName + " expects " + this.shortNameArticle + " " +
(this.tokenInfo.shortName + ", but was given a custom token.");
}
else if (isLegacyCustomToken) {
errorMessage = this.tokenInfo.verifyApiName + " expects " + this.shortNameArticle + " " +
(this.tokenInfo.shortName + ", but was given a legacy custom token.");
}
else {
errorMessage = 'Firebase ID token has no "kid" claim.';
}
errorMessage += verifyJwtTokenDocsMessage;
}
else if (header.alg !== this.algorithm) {
errorMessage = this.tokenInfo.jwtName + " has incorrect algorithm. Expected \"" + this.algorithm + "\" but got " +
"\"" + header.alg + "\"." + verifyJwtTokenDocsMessage;
}
else if (payload.aud !== this.projectId) {
errorMessage = this.tokenInfo.jwtName + " has incorrect \"aud\" (audience) claim. Expected \"" +
this.projectId + "\" but got \"" + payload.aud + "\"." + projectIdMatchMessage +
verifyJwtTokenDocsMessage;
}
else if (payload.iss !== this.issuer + this.projectId) {
errorMessage = this.tokenInfo.jwtName + " has incorrect \"iss\" (issuer) claim. Expected " +
("\"" + this.issuer + "\"") + this.projectId + "\" but got \"" +
payload.iss + "\"." + projectIdMatchMessage + verifyJwtTokenDocsMessage;
}
else if (typeof payload.sub !== 'string') {
errorMessage = this.tokenInfo.jwtName + " has no \"sub\" (subject) claim." + verifyJwtTokenDocsMessage;
}
else if (payload.sub === '') {
errorMessage = this.tokenInfo.jwtName + " has an empty string \"sub\" (subject) claim." + verifyJwtTokenDocsMessage;
}
else if (payload.sub.length > 128) {
errorMessage = this.tokenInfo.jwtName + " has \"sub\" (subject) claim longer than 128 characters." +
verifyJwtTokenDocsMessage;
}
if (typeof errorMessage !== 'undefined') {
return Promise.reject(new error_1.FirebaseAuthError(error_1.AuthClientErrorCode.INVALID_ARGUMENT, errorMessage));
}
return this.fetchPublicKeys().then(function (publicKeys) {
if (!publicKeys.hasOwnProperty(header.kid)) {
return Promise.reject(new error_1.FirebaseAuthError(error_1.AuthClientErrorCode.INVALID_ARGUMENT, _this.tokenInfo.jwtName + " has \"kid\" claim which does not correspond to a known public key. " +
("Most likely the " + _this.tokenInfo.shortName + " is expired, so get a fresh token from your ") +
"client app and try again."));
}
else {
return _this.verifyJwtSignatureWithKey(jwtToken, publicKeys[header.kid]);
}
});
};
const admin = require('firebase-admin');
var serviceAccount = require('./firebase-adminsdk-file.json');
admin.initializeApp({
credential: admin.credential.cert(serviceAccount),
databaseURL: "{{ databaseURL }}"
});
const idToken = `{{ token }}`;
admin.auth()
.verifyIdToken(idToken)
.then((user) => {
console.log(user.uid)
}).catch((reason) => {
console.log(reason)
});
我希望输出是有效的用户 ID
但我收到此错误:
{ code: 'auth/argument-error',
message:
'Decoding Firebase ID token failed. Make sure you passed the entire string JWT which represents an ID token. See https://firebase.google.com/docs/auth/admin/verify-id-tokens for details on how to retrieve an ID token.' },
codePrefix: 'auth' }
firebase 管理员版本:
"firebase-admin": "^7.3.0"
更新 当我添加这一行时,它可以工作
let idToken = `{{ token }}`;
idToken = idToken.split(":")[0];
我必须删除身份验证令牌的最后一部分吗?
":AIzaSyA13xxxxxxxxxx"
解决方案
推荐阅读
- excel - Excel VBA:从其他两个的排列创建一个表
- javascript - TypeError:无法读取未定义的属性“searchContact”
- java - macOS 上的 frame.setSize 问题(java 代码)
- python - 使用 pandas,找到两个 DataFrame 之间的相交区域?
- docker - 远程 AWS 上的 Zalenium 集线器 IP
- android - Android 上的“su”既不报错也不生效。如何在 root 设备上成功运行 su 命令?
- javascript - 如何优化重新训练的 ssd_mobilenet_v2_coco 以进行 tensorflowjs 推理?
- php - 我尝试使用 PHPMailer 发送电子邮件,但出现错误:
- javascript - 如何编写可重用和模块化的 Redux 选择器?
- mysql - 如何通过聚合和标记来编写a?