Skip to content

Instantly share code, notes, and snippets.

@jirawatee
Last active May 3, 2023 08:44
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 jirawatee/366d6bef98b137131ab53dfa079bd0a4 to your computer and use it in GitHub Desktop.
Save jirawatee/366d6bef98b137131ab53dfa079bd0a4 to your computer and use it in GitHub Desktop.
Code sample for verifying signature from LINE webhook
let text = JSON.stringify(req.body)
text = text.replace(/([\u2700-\u27BF]|[\uE000-\uF8FF]|\uD83C[\uDC00-\uDFFF]|\uD83D[\uDC00-\uDFFF]|[\u2011-\u26FF]|\uD83E[\uDD10-\uDDFF])/g, (e) => {
return "\\u" + e.charCodeAt(0).toString(16).toUpperCase() + "\\u" + e.charCodeAt(1).toString(16).toUpperCase()
})
const signature = crypto.createHmac('SHA256', LINE_CHANNEL_SECRET).update(text).digest('base64').toString()
if (signature !== req.headers['x-line-signature']) {
return res.status(401).send('Unauthorized')
}
@stephenhand
Copy link

Thanks for the video & this gist, it helped solve my issue

The above code is a little broken though, it tries to escape 2 characters in all cases, even though the regex can match single unicode characters. This would result in NaNs polluting the string and causing the incorrect signature to be generated.

This replacer arrow function should work better:

(emojiChars) =>
    emojiChars
      .split('')
      .map((c) => `\\u${c.charCodeAt(0).toString(16).toUpperCase()}`)
      .join('')

Also, I'm not sure exactly what characters you specifically seek to match, but if it's emojis, using the built in unicode matchers might be cover more cases, i.e. /\p{Emoji_Presentation}/gu

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment