서버리스 기능에서 Shopify Webhook 확인

last post에서 서버리스 기능을 사용하여 헤드리스 CMS와 Shopify 제품 데이터를 동기화하는 기본 접근 방식을 설명했습니다. 반갑지 않은 API 호출과 악의적인 데이터 수정 시도를 방지하기 위해 Shopify에서 제공하는 HMAC based verification procedure을 사용할 수 있습니다.

비밀 키를 사용하여 요청 본문을 HMAC 해시로 소화할 수 있습니다. 이것을 요청 헤더에 제공된 HMAC 해시와 비교하면 요청이 유효한지 여부를 확인할 수 있습니다. 수신된 웹후크의 출처를 확인하고 동기화 워크플로우의 무결성을 보장하기 위해 API를 약간만 수정하면 됩니다.

전제 조건



이 예에서는 built-in API routes 의 Next.jsVercel에서 제공하는 서버리스 기능을 사용하고 있습니다. 노드 기반 서버리스 또는 람다 기능을 배포하는 다른 프레임워크나 플랫폼도 잘 작동해야 합니다. 또한 Webhook을 가져오려면 Shopify Shop 인스턴스가 필요합니다. 일반적으로 개발자로서 무료로 만들 수 있습니다. 지난 게시물에서 논의한 예제를 계속해서 구축합니다.

또한 요청 본문을 HMAC 해시로 소화하기 위한 비밀 키가 필요합니다. 맨 아래 스토어 대시보드의 "알림"설정에서 찾을 수 있습니다. 안전하고 건전하게 유지하기 위해 프로젝트의 환경 변수에 저장하는 것이 좋습니다.



원시 몸 필요



클라이언트에 대해 이것을 설정하는 첫 번째 접근 방식에서 다음과 같은 불쾌한 함정을 발견했습니다. 웹후크 요청 본문과 비밀 키에서 올바른 HMAC 다이제스트를 생성하려면 요청 원시 본문이 필요합니다. Next.js는 deactivate the default body parser 옵션을 제공합니다. 이렇게 하려면 http.IncomingMessage 스트림을 직접 처리하고 내부에서 요청Buffer을 추출해야 합니다. 우리는 raw-body라는 라이브러리를 사용하여 정확히 이 작업을 수행할 것입니다.

import getRawBody from 'raw-body'

export default async function (req, res) {
  // We need to await the Stream to rexiece the complete body Buffer
  const body = await getRawBody(req)
  // ...
}

// We turn off the default bodyParser provided by Next.js
export const config = {
  api: {
    bodyParser: false,
  },
}


HMAC 다이제스트 만들기



이제 변수에 저장된 원시 본문Buffer을 얻었으므로 비밀 키를 사용하여 원시 본문을 hmac 해시로 소화하고 결국 X-Shopify-Hmac-SHA256 헤더 문자열과 비교합니다. HMAC 헤더는 base64로 인코딩되어 있으므로 다이제스트도 인코딩해야 합니다. 다이제스트와 헤더가 같으면 웹후크가 유효한 것으로 간주될 수 있습니다.

노드는 hmac 다이제스트를 생성하기 위해 crypto 모듈과 해당 crypto.createHmac() 메서드를 제공합니다. 모듈을 API 경로로 가져오고 이전 단계에서 준비한 데이터를 입력합니다. 암호화 모듈에 대한 자세한 내용은 have a look at the official documentation .

import getRawBody from 'raw-body'
import crypto from "crypto"

export default async function (req, res) {
  // We need to await the Stream to recieve the complete body Buffer
  const body = await getRawBody(req)
  // Get the header from the request
  const hmacHeader = req.headers['x-shopify-hmac-sha256']
  // Digest the data into a hmac hash
  const digest = crypto
    .createHmac('sha256', process.env.SHOPIFY_SECRET)
    .update(body)
    .digest('base64')
  // Compare the result with the header
  if (digest === hmacHeader) {
    // VALID - continue with your tasks
    res.status(200).end()
  } else {
    // INVALID - Respond with 401 Unauthorized
    res.status(401).end()
  }
}

// We turn off the default bodyParser provided by Next.js
export const config = {
  api: {
    bodyParser: false,
  },
}


마무리



가격 및 재고와 관련된 데이터 전송을 안전하게 유지하는 것은 일반적으로 헤드리스 전자 상거래에 중요한 기능입니다. 몇 줄의 코드만으로 서버리스 기능에서 Shopify 웹후크 시스템에 내장된 유효성 검사를 활용할 수 있습니다.

좋은 웹페이지 즐겨찾기