#node.js #google-api #jwt
#node.js #google-api #jwt
Вопрос:
У меня есть бот в NodeJS, подключенный к Google Chat с использованием конечных точек HTTPs. Я использую экспресс для получения запросов. Мне нужно убедиться, что все запросы поступают от Google, и я хочу сделать это, используя токен-носитель, который Google отправляет с запросами.
Моя проблема в том, что я изо всех сил пытаюсь найти способ проверки токенов.
Я захватил токен и попытался получить запросы на https://oauth2.googleapis.com/tokeninfo?id_token=ey … (где ey… является началом токена).
Который возвращает:
"error": "invalid_token",
"error_description": "Invalid Value"
}
Я попробовал то, что рекомендует Google:
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);
И получите следующую ошибку:
Ошибка: pem не найден для конверта: {«alg»:»RS256″, «kid»:»d … 1″, «typ»:»JWT»}
Есть идеи, куда мне следует направиться отсюда?
Редактировать: https://www.googleapis.com/service_accounts/v1/metadata/x509/chat@system.gserviceaccount.com нашел это, исследуя, как его использовать. Ребенок соответствует тому, который я получаю.
Ответ №1:
В конце концов, это сработало.
Вам нужно нажать: https://www.googleapis.com/service_accounts/v1/metadata/x509/chat@system.gserviceaccount.com чтобы получить JSON-файл, содержащий ключи, связанные с их дочерними элементами.
Затем, когда поступает запрос, используйте jsonwebtoken (NPM) для декодирования токена и извлечения дочернего элемента из заголовка.
Используйте KID, чтобы найти соответствующий открытый ключ в ответе с веб-сайта выше, затем используйте функцию проверки, чтобы убедиться, что токен соответствует открытому ключу.
Вам также необходимо передать параметры аудитории и эмитента для проверки, чтобы подтвердить, что именно ваша учетная запись службы попадает в бот.
Ответ №2:
Приведенное выше решение может быть правильным для Google Chat, но, по моему опыту, службы Google (например, задачи Google) используют токены OIDC, которые можно проверить с verifyIdToken
помощью функции.
Добавляю свое решение здесь, поскольку ваш вопрос / ответ был самым близким, что я смог найти для своей проблемы
Итак, в случае, если вам нужно подписать запрос из вашего собственного кода
на клиенте отправляйте запросы с помощью токена OIDC
import {URL} from 'url';
import {GoogleAuth} from 'google-auth-library';
// will use default auth or GOOGLE_APPLICATION_CREDENTIALS path to SA file
// you must validate email of this identity on the server!
const auth = new GoogleAuth({});
export const request = async ({url, ...options}) => {
const targetAudience = new URL(url as string).origin;
const client = await auth.getIdTokenClient(targetAudience);
return await client.request({...options, url});
};
await request({ url: 'https://my-domain.com/endpoint1', method: 'POST', data: {} })
на сервере проверьте OIDC (идентификационный токен)
const auth = new OAuth2Client();
const audience = 'https://my-domain.com';
// to validate
const token = req.headers.authorization.split(/[ ] /)[1];
const ticket = await auth.verifyIdToken({idToken: token, audience });
if (ticket.getPayload().email !== SA_EMAIL) {
throw new Error('request was signed with different SA');
}
// all good
Подробнее о токенах Google OpenID Connect