Атрибут Firebase Auth ID имеет неправильную претензию "aud"
Я пытаюсь проверить бэкэнд idToken. Пользователь успешно вошел в систему на стороне клиента firebase, но когда я пытаюсь проверить idToken на моем бэкэнд, я получаю сообщение об этом не очень полезное сообщение
У токена идентификатора Firebase Auth ID неверная заявка "aud"
Сообщение об ошибке, похоже, стало немного более информативным и сводится к отсутствию имени проекта в ключе авторизации:
Ошибка: токен Firebase ID имеет неправильную претензию "ауди" (аудитория). Ожидаемый "stripmall-0000", но получил "617699194096-0aafcvsml0gke61d6077kkark051f3e1.apps.googleusercontent.com". Убедитесь, что маркер ID поступает из одного проекта Firebase, так как учетной записи службы, используемой для аутентификации этого SDK. Видеть https://firebase.google.com/docs/auth/server/verify-id-tokens для подробнее о том, как получить токен ID.
Кто-нибудь с малейшей идеей может ошибаться? Я правильно получаю tokenId от клиента, поэтому это не должно быть проблемой. Искренние пристрастия, если это было задано раньше или тривиально каким-либо другим способом.
firebase.initializeApp({
serviceAccount: {
"type": "service_account",
"project_id": <project id here>,
"private_key_id": <key id goes here>,
"private_key": <key goes here>
"client_email": <email goes here>,
"client_id": <my client id>,
"auth_uri": "https://accounts.google.com/o/oauth2/auth",
"token_uri": "https://accounts.google.com/o/oauth2/token",
"auth_provider_x509_cert_url": "https://www.googleapis.com/oauth2/v1/certs",
"client_x509_cert_url": <url goes here>
},
databaseURL: <my db url here>
});
router.post("/verify", function (req, res) {
firebase.auth().verifyIdToken(req.body.idToken).then(function (decodedToken) {
var uid = decodedToken.sub;
res.send(uid);
}).catch(function (error, param2) {
console.log(error); // 'Firebase Auth ID token has incorrect "aud" claim'
});
});
Ответы
Ответ 1
Возможно, проблема заключается в том, что вы пытаетесь использовать токен JWT, возвращаемый одной из функций auth()
, таких как firebaseRef.auth().signInWithPopup()
. Они возвращают токен JWT, однако утверждения auth, вероятно, будут неправильными и не будут проходить проверку на verifyIdToken
. Это было подтверждено технической поддержкой firebase.
Вы должны использовать функцию firebaseRef.auth().currentUser.getToken()
. Этот токен пройдет проверку.
Ответ 2
Проблема для меня была не в токене, а в том, что мне нужно было инициализировать свой бэкэнд, используя служебную учетную запись. Делая это, вы также можете тестировать и отлаживать с локального сервера разработки.
FileInputStream serviceAccount = new FileInputStream("path/to/serviceAccountKey.json");
FirebaseOptions options = new FirebaseOptions.Builder()
.setCredentials(GoogleCredentials.fromStream(serviceAccount))
.setDatabaseUrl("https://<DATABASE_NAME>.firebaseio.com/")
.build();
FirebaseApp.initializeApp(options);
FirebaseAuth firebaseAuth = FirebaseAuth.getInstance();
// Get the FB uid from the token
FirebaseToken decodedToken = firebaseAuth.verifyIdTokenAsync(token).get();
String uid = decodedToken.getUid();
источник: https://firebase.google.com/docs/admin/setup
Ответ 3
Если вы работаете локально, это сообщение об ошибке также появляется, если у вас есть неправильная переменная среды GOOGLE_APPLICATION_CREDENTIALS. Проверьте, соответствует ли ключ JSON, заданный с помощью этой переменной среды, проекту.
Ответ 4
TL;DR: как уже упоминалось в другом ответе, вы неправильно инициализируете приложение.
Хотя, я немного опоздал по этому поводу, у меня была та же проблема, поэтому я решил погрузиться и посмотреть, что происходит за капотом.
Прежде всего, если API не изменился с тех пор, как был задан этот вопрос, serviceAccount
не существует как свойство как часть интерфейса AppOptions
, поэтому, вероятно, вы получили ошибку. Таким образом, я буду считать, что у вас там имеется в виду, что в credential
ключа.
Во-вторых, вы видите, что эта ошибка выдается по адресу https://github.com/firebase/firebase-admin-node/blob/master/src/auth/token-verifier.ts (строка 187 на момент написания этой статьи), где утверждение aud
в токене сравнивается с this.projectId
.
Теперь, как упоминают другие ответы, это может быть потому, что токен, который вы пытаетесь проверить, был создан не на стороне клиента, а каким-то другим пользовательским методом, и в этом случае утверждение aud
может отсутствовать, что-то совершенно случайное, или что-то, что определенно не будет соответствовать вашему projectId
так что вы должны проверить это в первую очередь.
Однако, если вы уверены, что токен был создан на стороне клиента, он сводится к тому, что projectId
не установлен или, по крайней мере, не настроен так, как вы ожидаете. Если вы посмотрите на метод getProjectId()
в https://github.com/firebase/firebase-admin-node/blob/master/src/utils/index.ts (строка 66 на момент написания этой статьи), вы увидите что projectId
определяется в одном из 3 -х способов: от app.options
объекта непосредственно из projectId
собственности в app.options.credential
, или из process.env.GOOGLE_CLOUD_PROJECT || process.env.GCLOUD_PROJECT
process.env.GOOGLE_CLOUD_PROJECT || process.env.GCLOUD_PROJECT
. Это означает, что если projectId
не установлен, и если ваш проект размещен на GCloud (который я предполагаю, что stripmall-0000
есть), то Google будет автоматически использовать текущую среду ProjectID для всего, что касается firebase-AUTH, не ProjectID из исходный проект.
Итак, три варианта:
-
Инициализируйте ваше приложение с AppOptions
projectId
установленным непосредственно в AppOptions
:
firebase.initializeApp({
databaseURL: <my db url here>,
// Set your projectId directly here in options:
projectId: <your-projectId-here>
});
-
Или, возможно, лучше сделать это, правильно установив объект учетных данных:
firebase.initializeApp({
credentials: admin.credential.cert(<<path-to-your-certificate> || <admin.ServiceAccount object>>),
databaseURL: <my db url here>
});
-
Или просто разместите приложение в том же проекте, что и ваше приложение Firebase (теперь, когда они являются частью одной экосистемы), чтобы переменные среды были одинаковыми. (На самом деле не 100% об этом, но я предполагаю, что именно так работают firebase-функции или облачные функции)