У меня есть время, пытаясь использовать Google OAuth для аутентификации пользователей в моем экспресс-приложении node. Я могу успешно выполнить OAuth, который возвращает ответ так:
{
access_token: 'token string',
id_token: 'id.string',
expires_in: 3599,
token_type: "Bearer"
}
Это все имеет смысл, но я не могу для жизни меня понять, как декодировать JWT. Я немного неопытен во всем этом, так что это все немного чуждо мне.
Следуя инструкциям, перечисленным здесь: https://developers.google.com/accounts/docs/OAuth2Login#validatinganidtoken Я пытаюсь декодировать JWT локально в приложении node.
Я установил https://github.com/hokaccha/node-jwt-simple в мою среду node.
И я вполне уверен, что мне нужно использовать этот сертификат (https://www.googleapis.com/oauth2/v1/certs) во всем этом, чтобы каким-то образом его декодировать, но я немного потеря здесь. Я действительно не понимаю, как получить сертификат в моем приложении node, и после этого, как использовать его с node -jwt-simple. И я также не понимаю, как я знаю, когда мне нужно вытащить свежий сертификат, а также использовать кешированный.
Кто-нибудь есть с некоторым опытом в этом, который может мне помочь?
Спасибо за любую помощь. На данный момент я совершенно не понимаю.
** Обновление **
Итак, я сделал некоторый прогресс... Вроде. Вызвав jwt.decode(id_token, certificate, true); Я могу успешно декодировать токен. Даже если сертификат var является пустым объектом {}. Это оставляет мне еще 3 вопроса. 1: Каков наилучший способ получить сертификат в моем экспресс-приложении, используя URL-адрес Google? 2: Как я узнаю, когда мне понадобится новая версия? 3: Кажется, что передача true для noVerify (3rd arg in jwt.decode) - ужасная идея. Как я могу заставить это работать, не передавая это? Похоже, что jwt-simple ожидает hs256, а токен использует rs256.
Опять же, я слишком неопытен в этом, так что я могу быть здесь вне базы.
* ОБНОВЛЕНИЕ * Благодаря помощи Nat, я смог получить эту работу! Я думаю, что я пробовал каждый модуль JWT и JWS node. Я наконец приземлился следующим образом: Я обнаружил, что ни один из модулей, на которые я смотрел, не сделал то, что я хотел из коробки. Я создал следующие вспомогательные методы jwt-декодирования, которые я использую для декодирования id_token, поэтому я могу получить малыша из заголовка.
module.exports = {
decodeJwt: function (token) {
var segments = token.split('.');
if (segments.length !== 3) {
throw new Error('Not enough or too many segments');
}
// All segment should be base64
var headerSeg = segments[0];
var payloadSeg = segments[1];
var signatureSeg = segments[2];
// base64 decode and parse JSON
var header = JSON.parse(base64urlDecode(headerSeg));
var payload = JSON.parse(base64urlDecode(payloadSeg));
return {
header: header,
payload: payload,
signature: signatureSeg
}
}
}
function base64urlDecode(str) {
return new Buffer(base64urlUnescape(str), 'base64').toString();
};
function base64urlUnescape(str) {
str += Array(5 - str.length % 4).join('=');
return str.replace(/\-/g, '+').replace(/_/g, '/');
}
Я использую это декодирование, чтобы определить, нужно ли мне использовать новый публичный сертификат: https://www.googleapis.com/oauth2/v1/certs
Затем я использую этот открытый сертификат и node -jws (https://github.com/brianloveswords/node-jws) jws.verify(id_token, cert), чтобы проверить подпись!
Ура! Еще раз спасибо за дополнительное объяснение, которое вы дали в своем ответе. Это помогло мне понять, что я даже пытался сделать. Надеюсь, это тоже поможет другим.