2011-12-18 2 views
3

Я пытаюсь реализовать библиотеку Facebook с node.js, а подпись запроса не работает. У меня есть пример PHP seen here, переведенный на узел. Я пробую это с приведенным здесь примером, где секрет - это строка «секрет». Мой код выглядит следующим образом:node.js hmac.digest() output кажется неправильным

var signedRequest = request.signed_request.split('.'); 

var sig = b64url.decode(signedRequest[0]); 

var expected = crypto.createHmac('sha256', 'secret').update(signedRequest[1]).digest(); 

console.log(sig == expected); // false 

Я не могу console.log декодированные строки сами, потому что у них есть специальные символы, которые вызывают консоль, чтобы очистить (если у вас есть предложение, чтобы получить вокруг этого, пожалуйста, дайте мне знать), но Я могу вывести кодировки b64url из них.

Ожидаемое кодируются сиг, как вы можете видеть на документации FB, является

vlXgu64BQGFSQrY0ZcJBZASMvYvTHu9GQ0YM9rjPSso 

Мои expected значение при кодировании, является

wr5Vw6DCu8KuAUBhUkLCtjRlw4JBZATCjMK9wovDkx7Dr0ZDRgzDtsK4w49Kw4o 

Так почему же я думаю, что это digest, что это неправильно ? Может, ошибка на моей стороне? Хорошо, если я выполню точный пример в PHP, указанный в документации, выдается правильный результат. Но если изменить hash_hmac вызов, поэтому последний параметр является ложным, выводя шестигранник, я получаю

YmU1NWUwYmJhZTAxNDA2MTUyNDJiNjM0NjVjMjQxNjQwNDhjYmQ4YmQzMWVlZjQ2NDM0NjBjZjZiOGNmNGFjYQ== 

Теперь, если я вернусь к моему яваскрипту коду и изменить свой HMAC код .digest("hex") вместо стандартного "binary" и зарегистрируйте кодировку base64 результата, я получаю ... удивление!

YmU1NWUwYmJhZTAxNDA2MTUyNDJiNjM0NjVjMjQxNjQwNDhjYmQ4YmQzMWVlZjQ2NDM0NjBjZjZiOGNmNGFjYQ 

То же самое, за исключением признаков, отмеченных символом ==, но я думаю, что это консольная вещь. Я не могу представить, что это проблема, без них это даже не допустимая длина строки base64.

Итак, почему метод дайджеста выводит правильный результат при использовании hex, но неправильный ответ при использовании двоичного кода? Является ли двоичный файл не совсем таким же, как «сырой» вывод PHP-эквивалента? И если это так, то какой правильный способ назвать это?

ответ

0

Я партнер Tesserex. Я считаю, что ответ, возможно, был комбинацией ответа самого Тессерекса и ответа Juicy Scripter. Мы все еще использовали Node ver. 0.4.7. Об этой ошибке Tesserex можно найти здесь: https://github.com/joyent/node/issues/324. Я не совсем уверен, что эта ошибка затронула нас, но это кажется хорошей возможностью. Мы обновили Node до версии 0.6.5 и применили решение Juicy Scripter, и теперь все работает. Спасибо.

В качестве примечания относительно использования существующих библиотек. Большинство существующих библиотек требуют экспресс, это то, что мы пытаемся избежать, с некоторыми особенностями нашего приложения. Кроме того, существующие библиотеки склонны предполагать, что вы используете node.js, как веб-сервер, и одновременно отвечаете на один запрос пользователей. Мы используем постоянные соединения с websockets, и наш клиент facebook будет обрабатывать данные сеанса для нескольких пользователей одновременно. В конце концов, я надеюсь, что наш клиент с открытым исходным кодом Facebook будет использоваться с такими приложениями, как наша.

+0

Только что проверено, а код, который я предоставил, отлично работает с [v0.4.7] (https://github.com/joyent/node/фиксации/c85455a954411b38232e79752d4abb61bb75031b) ... –

0

На самом деле нет никаких проблем с digest, результаты b64url.decode в utf8 кодировкой по умолчанию (который может быть задан второй параметр), если вы используете:

var sig = b64url.decode(signedRequest[0], 'binary'); 
var expected = crypto.createHmac('sha256', 'secret').update(signedRequest[1]).digest(); 
// sig === expected 

подпись и результат дайджеста будет одна и та же.

Вы также можете проверить это путем поворота digest результатов в utf8 закодированную строку:

var sig = b64url.decode(signedRequest[0]); 
var expected = crypto.createHmac('sha256', 'secret').update(signedRequest[1]).digest(); 
var expected_buffer = new Buffer(expected_sig.digest(), 'binary'); 
// sig === expected_buffer.toString() 

Также вы можете рассмотреть возможность использования существующих библиотек, чтобы сделать такую ​​работу (и, возможно, больше), чтобы назвать некоторые из них:

1

Мы обнаружили, что это действительно ошибка в crypto lib, и это была известная проблема, зарегистрированная в github. Мы должны будем обновить и исправить ошибку.

+0

Вы можете указать ссылку на эту проблему, чтобы знать? .. –