みかづきブログ・カスタム

基本的にはちょちょいのほいです。

VercelのプレビューURLに対して外部からPOSTリクエストを投げると401が返ってくる際の対策 💻

結論

「Project Setting > Deployment Protection > Vercel Authentication」をDisabledに設定すればOKです。


ことの発端

普通はこんな使い方しないと思うのですが、LINE BotのWebHookに使うためのAPIをVercelにデプロイした際に気がつきました。

blog.kimizuka.org
blog.kimizuka.org

Production Branchに設定したブランチ以外のブランチをpushした際に自動的に生成されるプレビューサイトのURLに対し、POSTリクエストを送ると401が返ってくるようです。

Vercel Authenticationが有効になっていると、

Response {
  [Symbol(realm)]: null,
  [Symbol(state)]: {
    aborted: false,
    rangeRequested: false,
    timingAllowPassed: true,
    requestIncludesCredentials: true,
    type: 'default',
    status: 401,
    timingInfo: {
      startTime: 58.99487495422363,
      redirectStartTime: 0,
      redirectEndTime: 0,
      postRedirectStartTime: 58.99487495422363,
      finalServiceWorkerStartTime: 0,
      finalNetworkResponseStartTime: 0,
      finalNetworkRequestStartTime: 0,
      endTime: 0,
      encodedBodySize: 0,
      decodedBodySize: 0,
      finalConnectionTimingInfo: null
    },
    cacheState: '',
    statusText: 'Unauthorized',
    headersList: HeadersList {
      cookies: [Array],
      [Symbol(headers map)]: [Map],
      [Symbol(headers map sorted)]: null
    },
    urlList: [ URL {} ],
    body: { stream: undefined }
  },
  [Symbol(headers)]: HeadersList {
    cookies: [
      '_vercel_sso_nonce=XXXXXXXXXXXXXXXX; Max-Age=3600; Path=/; Secure; HttpOnly; SameSite=Lax'
    ],
    [Symbol(headers map)]: Map(11) {
      'cache-control' => [Object],
      'connection' => [Object],
      'content-length' => [Object],
      'content-type' => [Object],
      'date' => [Object],
      'server' => [Object],
      'set-cookie' => [Object],
      'strict-transport-security' => [Object],
      'x-frame-options' => [Object],
      'x-robots-tag' => [Object],
      'x-vercel-id' => [Object]
    },
    [Symbol(headers map sorted)]: null
  }
}

と、401が返ってきますが、

Vercel Authenticationを無効にすると、200が返ってくるようになります。

Response {
  [Symbol(realm)]: null,
  [Symbol(state)]: {
    aborted: false,
    rangeRequested: false,
    timingAllowPassed: true,
    requestIncludesCredentials: true,
    type: 'default',
    status: 200,
    timingInfo: {
      startTime: 49.69470798969269,
      redirectStartTime: 0,
      redirectEndTime: 0,
      postRedirectStartTime: 49.69470798969269,
      finalServiceWorkerStartTime: 0,
      finalNetworkResponseStartTime: 0,
      finalNetworkRequestStartTime: 0,
      endTime: 0,
      encodedBodySize: 0,
      decodedBodySize: 0,
      finalConnectionTimingInfo: null
    },
    cacheState: '',
    statusText: 'OK',
    headersList: HeadersList {
      cookies: null,
      [Symbol(headers map)]: [Map],
      [Symbol(headers map sorted)]: null
    },
    urlList: [ URL {} ],
    body: { stream: undefined }
  },
  [Symbol(headers)]: HeadersList {
    cookies: null,
    [Symbol(headers map)]: Map(17) {
      'access-control-allow-headers' => [Object],
      'access-control-allow-methods' => [Object],
      'access-control-allow-origin' => [Object],
      'cache-control' => [Object],
      'connection' => [Object],
      'content-encoding' => [Object],
      'content-type' => [Object],
      'date' => [Object],
      'server' => [Object],
      'strict-transport-security' => [Object],
      'vary' => [Object],
      'x-matched-path' => [Object],
      'x-robots-tag' => [Object],
      'x-vercel-cache' => [Object],
      'x-vercel-execution-region' => [Object],
      'x-vercel-id' => [Object],
      'transfer-encoding' => [Object]
    },
    [Symbol(headers map sorted)]: null
  }
}

デフォルトでは有効になっているので、こういう使い方をしたい場合は無効にしましょう。

僕の場合は、Page Routerのブランチをプロダクションブランチに設定していたため、App Routerで401が返ってくるという現象だと思いこみ、デバッグに時間が掛かってしまいました。
よくよく考えると、初めにNext.jsの問題なのか、Vercelの問題なのか切り分けられればよかったですね。