Skip to content

Instantly share code, notes, and snippets.

@dibikhin
Last active July 14, 2020 09:19
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save dibikhin/16c6df88cee2fefa3441c0c6d6e34fd3 to your computer and use it in GitHub Desktop.
Save dibikhin/16c6df88cee2fefa3441c0c6d6e34fd3 to your computer and use it in GitHub Desktop.
testing parsing fb signed requests
'use strict'
const crypto = require('crypto')
const secret1 = 'appsecret'
const payload1 = {
algorithm: 'HMAC-SHA256',
expires: 1291840400,
issued_at: 1291836800,
user_id: '218471'
}
console.log(
'payload', payload1,
)
const signedRequest = signRequest({
payload: payload1,
secret: secret1,
})
console.log(
'signedRequest:', signedRequest,
)
const parsedRequest = parseSignedRequest({
signedRequest,
secret: secret1,
})
console.log(
'parsedRequest:', parsedRequest,
)
function signRequest({ payload, secret, }) {
const jsonPayload = JSON.stringify(payload)
const payloadBin = Buffer.from(jsonPayload, 'utf8')
const base64Payload = base64Encode(payloadBin)
const urlEncodedPayload = urlEncode(base64Payload)
const sigBinary = hashHmacSha256(urlEncodedPayload, secret)
const base64Sig = base64Encode(sigBinary)
const urlEncodedSig = urlEncode(base64Sig)
return `${urlEncodedSig}.${urlEncodedPayload}`
}
function parseSignedRequest({ signedRequest, secret, }) {
const [urlEncodedSig, urlEncodedPayload] = signedRequest.split('.')
const base64Sig = urlDecode(urlEncodedSig)
const sigBinary = base64Decode(base64Sig)
const base64Payload = urlDecode(urlEncodedPayload)
const payloadBin = base64Decode(base64Payload)
const payload = payloadBin.toString('utf8')
const expectedSig = hashHmacSha256(urlEncodedPayload, secret)
if (!sigBinary.equals(expectedSig)) {
console.error(
'Signatures differ. Expected:', expectedSig.toString('hex'),
'Actual:', sigBinary.toString('hex'),
)
return null
}
return JSON.parse(payload)
}
function hashHmacSha256(data, secret) {
return crypto
.createHmac('sha256', secret)
.update(data)
.digest()
}
function base64Encode(data) {
return data.toString('base64')
}
function base64Decode(str) {
return Buffer.from(str, 'base64')
}
function urlEncode(str) {
return str
.replace(/\//g, '_')
.replace(/\+/g, '-')
}
function urlDecode(str) {
return str
.replace(/\_/g, '\\')
.replace(/\-/g, '+')
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment