カスタムAPI連携のトラブルシューティング
このガイドでは、API ベースの統合を手作業で実装する際の一般的な問題と、その解決策について説明します。これらのアドバイスは、ご自身のアプリケーションやフレームワークに合わせて調整する必要があります。
通常のサポートチャネルを通じて、カスタム統合に関するサポートを提供することはできません。これは、当社の管理が及ばない要因が数多く存在するからです。カスタム統合の構築自体は比較的簡単ですが、HTTPの基礎を十分に理解している経験豊富な開発者である必要があります。
以下で説明するすべての課題に対処した、実環境で実証済みの統合事例をご覧になりたい場合は、GitHubに掲載されている当社の統合事例をご参照ください:
- https://github.com/Crowdhandler/crowdhandler-cloudflare-integration
- https://github.com/Crowdhandler/crowdhandler-php-sdk
URLの除外に関する問題
アプリケーションにフロントコントローラーがある場合、個々のURLリクエストを許可または拒否するためにCrowdHandlerに確認を行う統合機能を通じて、すべてのリクエストをアプリケーションにルーティングしている可能性があります。これにより、以下の2つの問題が発生する可能性があります:
1. 不要なURLの確認
ユーザーがページを読み込むと、ブラウザはドメイン上の関連するすべてのページアセットを読み込みますが、これらのリクエストはフロントコントローラーを経由する可能性があります。これにより、不要なチェックが行われ、読み込み時間が長くなり、最終的にはアプリケーションのサーバー負荷が増大する恐れがあります。URLをチェックする前に、少なくとも以下の一般的なファイル拡張子は除外するようにしてください:
.css, .gif, .ico, .jpg, .jpeg, .js, .json, .mov, .mp4, .mpeg, .mpg, .png, .svg, .ttf, .otf, .eot, .woff, .woff2
また、待機室による保護を必要としないコンテンツに関連する、アプリケーション内のその他のパスも除外する必要があります。たとえば、すべての静的アセットを /static というサブディレクトリに保存している場合は、そのパスをチェックの対象から除外することができます。
2. キュー内のサードパーティ製サービスのブロック
上記のようにフロントコントローラーを使用しており、保護されたドメイン上のAPIを呼び出すサードパーティのサービスがある場合、これらのサービスはキューに引っかかり、クッキーを受け入れない可能性が高いため、処理が進まない可能性があります。ブロックされる可能性のある一般的なサードパーティのサービスには、次のようなものがあります:
- お客様のドメイン上のAPI(RPC、REST)を利用するサービス、プラグイン、またはアプリケーション
- 取引を確認するために、お客様のドメインに対してサーバーサイドのコールバックを行う決済サービス。
サービスが厳密に定義されたIP範囲を使用している場合は、バイパスルールにそのIP範囲を追加することで、それらの通信を通過させることができる場合があります。ただし、通常は、そもそもこれらのURLをチェック対象から除外しておく方が望ましいでしょう。
3. 管理者用URLのブロック
/admin などの URL を通じてバックエンドアプリケーションや CMS にログインする場合は、これらの URL も除外した方がよいかもしれません。また、オフィスや VPN の IP アドレスをバイパス対象に設定するのも、同様に効果的かもしれません。
クッキーに関する問題
カスタム統合に関して私たちが指摘する最大の問題は、ユーザーのCrowdHandlerトークンを追跡するためのCookieを正しく設定できていない点にあるかもしれません。
クッキーを使用している場合もあれば、別の形式のブラウザやサーバーサイドのセッションストレージを使用している場合もあります。ここでは、ユーザーのCrowdHandlerトークンを追跡するために使用するあらゆる保存方法を総称して「クッキー」と呼んでいますが、セッションの追跡にどのような手段を使用する場合でも、十分な注意を払う必要があります。
1. 読み取り可能なCookieを設定しなかった場合
統合では、ユーザーが初めてサイトにリダイレクトされた際に、そのユーザーのCrowdHandlerトークンを保存する必要があります。待合室からのリダイレクト後の最初のアクセスでは、URLにトークンが含まれていることを当てにできません。必ずクッキーが設定されるようにしてください。また、ユーザーがその後アクセスする可能性のあるパスにおいても、アプリケーションがそのクッキーを読み取れるように設定してください。
2. HTTPリダイレクトによりCookieが設定されない
統合処理でクッキーの設定に失敗する最も一般的な理由は、統合処理が実行される前にHTTPリダイレクトが発生し、URLにトークンを含めずにユーザーを新しいルートへリダイレクトしてしまうためです。こうしたリダイレクトルールは、Webサーバーの設定に含まれている場合もあれば、言語設定やログイン時のリダイレクトを処理するためにコードパス初期段階で実行される場合もあります。したがって、多言語サイトを運用している場合や、ユーザーログインを伴うパスを保護している場合は、特に注意が必要です。 解決策としては、リダイレクト時にトークンを含むクエリ文字列を必ず含めるようにするか、あるいは「待機室」から、すぐにリダイレクトされるURLへユーザーを直接送信しないようにすることです。
この問題については、専用のナレッジベース記事があります。詳細については、そちらをご覧ください。この記事は主にJavaScript連携のユーザーを対象としていますが、ご自身の連携環境でも同様の問題を再現できるはずです。
3. クッキーの更新を怠った場合
ユーザーがキューを複数回通過したり、セッションが期限切れになって新しいトークンが発行されたりするケースには、正当な理由が存在します。そのため、URL に crowdhandler トークンが含まれている場合や、API から新しいトークンが返ってきた場合は、必ずクッキーを更新して一致させる必要があります。そうしないと、統合機能で期限切れのトークンが使用され、ユーザーがキューに戻されてしまう可能性があります。
したがって、統合コードでは、URL内にトークンが含まれていないか確認してください。トークンが見つかった場合は、クッキー内にあるトークンではなく、URL内のトークンを使用して呼び出しを行ってください。その後、いずれの場合でも、APIから返されてきた形式が正しいトークンを信頼し、クッキーを設定してください。
4. クッキーの削除、または不正な値の設定
URLを確認したり、APIのレスポンスを解析してユーザーのCookieを更新すべきかどうかを判断する際は、コード内のどこかにバグがあり、誤ってnull、空、またはfalseの値が設定されないよう注意してください。フレームワークによっては、これをCookieの削除と解釈する場合があります。いずれにせよ、ユーザーが次のリクエストで無効なトークンを送信すると、新しいトークンが発行され、その結果、そのユーザーはキューの最後尾に回されてしまいます。
5. ユーザーを待合室にリダイレクトする際に、クッキーを設定しないこと。
厳密に言えば、このユーザーを待合室にリダイレクトする場合、クッキーを設定する必要はありません。しかし、常にクッキーを設定しておけば、統合の堅牢性は格段に高まります。これは、ユーザーが待合室での流れを完了する前に、何らかの理由で再びサイトに戻ってくる可能性があるためです。 その際、ユーザーを認識できれば、元の位置を維持したまま待合室に戻されます。認識できない場合は、待ち行列の最後尾という新しい位置で待合室に戻されます。ユーザーが待合室に長時間留まっている場合、新しいタブなどでサイトを再試行することは珍しくありません。特に、保護されたページへのリンクが記載されたメールを受け取っている場合はなおさらです。
6. クッキーに不適切な有効期限を設定すること、または一時的なセッションストレージに依存すること
上記のシナリオを考慮すると、.Net や PHP などのフレームワークが提供する組み込みのセッションストレージに通常設定されている 20 分間のタイムアウトでは、このシナリオには不十分である可能性があります。不安がある場合は、セッション Cookie または永続 Cookie を設定してください。
APIに関する問題
送信するパラメータや、受け取る可能性のある応答について、時間をかけて理解するようにしましょう。APIのリクエストやレスポンスに関して、よく見られる主な問題は以下の通りです:
1. APIに誤ったIPアドレスを送信する
リクエストリソースにIPアドレスを送信する際は、サーバー自身のIPアドレスや中継プロキシサーバーのIPアドレスではなく、必ずユーザーのIPアドレスを送信するようにしてください。同じIPアドレスを何度も送信すると、そのIPアドレスが特定され、ブロックされる可能性が高くなります。 本番環境でこの問題が発生した場合は、そのIPアドレスまたはIP範囲を「無視」に設定することで自動ブロックを回避できますが、正しいIPアドレスを特定できるよう、統合機能をテストして修正する必要があります。通常、Webサーバーがプロキシの背後にある場合、HTTPヘッダーの「X-Forwarded-For」から実際のIPアドレスを検出できます。こちらのガイドが参考になるかもしれません。
2. APIが応答すると仮定して
CrowdHandlerの存在意義は、お客様のサイトが利用できない状況でもサービスを提供し続けることにあります。しかし、一般的なインターネットのルーティングの問題やデータセンターのトラブルなど、サーバーが一時的にCrowdHandler APIに接続できなくなる正当な理由は数多く存在します。もしコードが常に正しい形式のレスポンスを受け取れることを前提としている場合、こうした状況が発生した際に、ユーザーに対して見苦しいエラーが表示されてしまう可能性があります。解決策:
- APIを呼び出す際は、タイムアウトを短く設定してください(2秒が最適です)。
- 呼び出しがタイムアウトした場合、または応答が不正な形式である場合は、どう対処するかを検討してください。 ほとんどの場合、このユーザーを信頼してURLへのアクセスを許可することをお勧めします。そうすることで、キューを実行していない間に障害が発生しても、ユーザーに支障が生じないからです。信頼度が低い状況では、ユーザーを待機室に誘導することを検討してください。CrowdHandlerの待機室は、APIとの接続を確立しようと試み、APIから適切な形式の応答を受け取るまで、ユーザーに対して可能な限りの対応を行います。
3. 応答形式の想定
ほとんどの場合、待合室での案内メッセージなどを含めた詳細な回答が届きます。以下に例を挙げます:
{
"result": {
"status": 1,
"token": "tok_7pDi5dRB2nUi",
"title": "The Herb Girls Reunited!",
"position": 964,
"promoted": 0,
"urlRedirect": null,
"onsale": "2021-12-06T12:20:00Z",
"message": "Booking is very busy right now. We appreciate your patience and will forward you shortly.",
"slug": "herb-girls",
"priority": null,
"priorityAvailable": 1,
"logo": "https://crowdhandler-templates.s3.amazonaws.com/public/94ea09f553bf57af84c21427c68b3c89fc64e2044c347522ba4ca01363ffaf8b/Queen Victoria Hall-logo-2.png",
"responseID": "e0abd8dbb8d2810fad16855622dcd45f",
"captchaRequired": 0,
"rate": 50,
"hash": null,
"ttl": 55
}
}
ただし、一部のステータスには、わずかな情報が記載されているものもあります。
たとえば、CrowdHandlerの待機室によって保護されていないURLへのリクエストを確認する場合などです。
{
"result": {
"status": 0,
"token": null,
"responseID": null,
"promoted": 1
}
}
その他、キーが無効な場合(HTTP 401エラー)、ルームが満員の場合(ステータス:5)、または送信元のIPアドレスがブロックリストに登録されている場合(ステータス:4)など、さまざまな応答が表示されることがあります。
解決策:
- 返ってくる応答コードの意味を理解するために、少し時間を割いてください。これらは、考慮すべき状況となる可能性があります。
- ユーザーにアクセス権を付与すべきか、それとも待機室に送るべきかを判断するには、「promoted」というブール型属性を確認するだけで十分です。この属性は、エラーが発生しない限り常に存在し、値は0か1のいずれかになります。 統合処理が非常に単純で、この属性のみを確認する場合には、さまざまな応答やステータスを理解する必要は実質的にありません。なぜなら、promotedが0であればユーザーを待合室に送ることができ、待合室側が適切な処理を行うからです。
- オブジェクト指向の観点から、レスポンスオブジェクトを常に一貫した状態に保つ必要があるアプリケーションを構築した場合、あるいはそのようなフレームワークを使用している場合は、まずレスポンスを表す独自のベースオブジェクトまたはクラスを作成し、妥当なデフォルト値を指定した上で、APIのレスポンスから返される値のみを設定するようにすべきです。