Я создаю собственный скрипт TamperMonkey для Firebase, чтобы провести локальное тестирование на моем веб-сайте. Вставляя UID данного пользователя аутентификации FireBase, я создаю для него customToken .
Вот мой текущий код
// ==UserScript==
// @name my-name
// @namespace my-namespace
// @version 1.0
// @author Myself
// @match XXXX-my-website-XXXX
// @require https://www.gstatic.com/firebasejs/6.6.2/firebase-app.js
// @require https://www.gstatic.com/firebasejs/6.6.2/firebase-auth.js
// @require https://cdnjs.cloudflare.com/ajax/libs/crypto-js/3.1.2/rollups/hmac-sha256.js
// @require https://cdnjs.cloudflare.com/ajax/libs/crypto-js/3.1.2/components/enc-base64-min.js
// @grant none
// ==/UserScript==
(function() {
function generateCustomToken(uid) {
if(typeof CryptoJS === undefined) {
alert("CryptoJS not found");
return;
}
// https://console.firebase.google.com/project/my-project-id/settings/serviceaccounts/adminsdk
var serviceAccount = { ... content of json service account file ... };
// https://firebase.google.com/docs/auth/admin/create-custom-tokens#create_custom_tokens_using_a_third-party_jwt_library
var header = {
"alg": "RS256",
"typ": "JWT"
};
var seconds = Math.trunc(new Date().getTime() / 1000);
var payload = {
iss : serviceAccount.client_email,
sub : serviceAccount.client_email,
aud : "https://identitytoolkit.googleapis.com/google.identity.identitytoolkit.v1.IdentityToolkit",
iat : seconds,
exp : seconds + (60*60), // Maximum expiration time is one hour
uid : uid,
claims : {
premium_account : false
}
};
// https://github.com/firebase/php-jwt/blob/master/src/JWT.php#L156
var segments = [];
segments.push(base64url(CryptoJS.enc.Utf8.parse(JSON.stringify(header))));
segments.push(base64url(CryptoJS.enc.Utf8.parse(JSON.stringify(payload))));
var signingInput = segments.join(".");
var secret = serviceAccount.private_key
.replace('-----END PRIVATE KEY-----', '') // remove head
.replace('-----BEGIN PRIVATE KEY-----', '') // remove tail
.replace(/\n/g, ''); // remove all new-line chars
segments.push(base64url(CryptoJS.HmacSHA256(signingInput, secret)));
return segments.join(".");
}
/**
* https://codepen.io/jpetitcolas/pen/zxGxKN
*/
function base64url(source) {
// Encode in classical base64
var encodedSource = CryptoJS.enc.Base64.stringify(source);
// Remove padding equal characters
encodedSource = encodedSource.replace(/=+$/, '');
// Replace characters according to base64url specifications
encodedSource = encodedSource.replace(/\+/g, '-');
encodedSource = encodedSource.replace(/\//g, '_');
return encodedSource;
}
function firebaseLogin(customToken) {
// FIXME omitted code, firebase initialize
firebase
.auth()
.signInWithCustomToken(customToken)
.then(function(response) {
alert("Success signInWithCustomToken");
})
.catch(function(error) {
alert("signInWithCustomToken ERROR\n" + error.code + "\n" + error.message);
});
}
})();
Я следовал различным примерам, которые нашел (я связал их в коде) и официальная документация для использования пользовательских клиентов.
Я прочитал код много раз, и все, кажется, в порядке, но из-за данной ошибки мне кажется, что я упускаю что-то очень простое, что я не могу увидеть при генерации токена jwt.
POST https://www.googleapis.com/identitytoolkit/v3/relyingparty/verifyCustomToken?key=xxx-my-api-key-xxx
{"token":"xxx-generated-custom-token-xxx","returnSecureToken":true}
HTTP RESPONSE 400
{
"error": {
"code": 400,
"message": "INVALID_CUSTOM_TOKEN",
"errors": [
{
"message": "INVALID_CUSTOM_TOKEN",
"domain": "global",
"reason": "invalid"
}
]
}
}
КакTamperMonkey, который предназначен для непосредственного запуска внутри браузера, среда Node или другие недоступны, поэтому я использую «сырые» библиотеки вместо более интегрированных.
Вы видите какую-либо ошибку при генерациижетон JWT?