メインコンテンツにスキップ

JSONウェブトークン(JWT)を使ったFin Messengerのユーザー認証

Fin Messengerとユーザーセッションをクロスユーザーなりすましやセッション盗難などから保護する方法。

JSONウェブトークン(JWT)は、第三者がログイン中のusersになりすまして会話を覗くのを防ぎます。すべてのFin顧客にJWT認証の実施を強く推奨します。

サイトにログイン中のusers向けにFin Messengerを設置している場合、悪意ある者がusersになりすましたり不正なデータを送信するのを防ぐために、必ずセキュリティを強化してください。​

セキュリティが不十分なMessengerでは、誰かがFin Messengerとやり取りし、メールアドレスやuser_idなどの既知の識別子を使って別のuserの身元を偽装する可能性があります。これにより攻撃者は実際のuserになりすまし、チームメイトにアクセスし、過去の会話や機密データにアクセスできる恐れがあります。


JSONウェブトークン(JWT)とは何ですか?

JWTはデータに署名する業界標準の方法です。通常、3つの部分に分かれており、ドットで区切られています。典型的なJWTは次のような形式です:header.payload.signature。

  • ヘッダーはトークンの種類(JWT)と署名アルゴリズム(例:HS256)を指定します。

  • ペイロードにはuserやセッションに関するクレーム(例:user_id、email)が含まれます。

  • 最後に、署名は秘密鍵やプライベートキーを使ってトークンが改ざんされていないことを保証します。


JSONウェブトークン(JWT)でMessengerを保護する利点は何ですか?

  • ユーザーIDの安全性向上: Messengerを保護することで、チームメイトは話しているuserが本当にそのuserであることを確信できます。

  • ユーザーデータのセキュリティ強化: Messengerを保護することで、Messenger APIを通じてuserに関するデータ属性を安全に送信できます。

  • 盗まれたセッションによるリスク軽減: JWTでMessengerを保護すると、トークンの有効期限を設定でき、usersのブラウザからトークンが盗まれた場合のデータ漏洩リスクを大幅に減らせます。短い有効期限を指定することでリスクが軽減されます。

  • より安全なFinとAI workflows: 複雑なプロセス、Actions、Workflowsに信頼できるuser情報が必要な場合でもFinに任せられます。

userのIDとデータを安全に送信し、トークンの有効期限を強制することで、JWTはFin Messengerを最も安全な状態に保ちます。


カスタマーエクスペリエンス

Fin MessengerでJWTを使う場合の体験は以下の通りです。

  • Messengerの統合は、JWTを含むIntercom('boot')リクエストでログイン中のuserを起動します。JWTにはworkspaceに送信したいすべてのuserデータが含まれます。JWTの署名は設定のMessenger秘密鍵で生成されます。

  • その後、workspaceはuserのブラウザにセッションクッキーを提供します。このクッキーのデフォルト有効期間は7日間で、ユーザー認証と更新に使用されます。

  • セッションが期限切れで新しいJWTが送信されない場合、userのセッションは終了します。userはログアウト状態のウェブサイト訪問者として新しいMessengerを見ます。会話履歴は含まれません。

  • MessengerがIntercom('boot')と有効なJWTで再起動されると、Messengerはuserを識別し、過去の会話と新しいセッションを表示します。同じデバイスでのログアウト中の活動も認証済みuserのアカウントに統合されます。

ヒント:

  • userのセッションクッキーの有効期間をデフォルトの7日より短くしたい場合は、session_duration Messenger属性でミリ秒単位のTTLを指定できます。

  • Fin MessengerからZendesk ticketsを作成し、特定の組織にticketsをルーティングしたい場合は、JWTにcompanyフィールドを含めることができます。idの値はZendesk組織のexternal ID(内部Zendesk IDではありません)と一致する必要があります。

注意: Finは引き継がれたウェブ会話のチームメイトの返信をFinに同期しますが、Salesforceケースには適用されません。ケースがSalesforce内のライブエージェントに再割り当てされると、Finは更新の取り込みを停止します。


インストール:JWTの生成と送信

ステップ1:アプリケーションにMessengerをインストールする

workspace固有のセットアップ手順は設定 > Fin Messenger > セキュリティで確認できます。

安全でないMessengerセットアップと安全なセットアップの主な違いは、ユーザーリクエストに追加のintercomUserJwtフィールドを含め、それを使ってuserを識別・更新する点です。

Javascriptスニペットにデータ属性を追加するオプションがあります。これはFin workspaceに送信したいデータを制御します。JWTでデータを送信するため、署名したくない属性(例:フロントエンド固有のデータ)のみをここに含めるべきです。

JWT以外にデータを送信しない場合は、api_baseとapp_id以外のデータをスニペットから削除できます。app_idはFin workspaceの固有識別子です。

user_idやemailなどのuser固有の識別子がない訪問者には、App IDのみを含むログアウト状態のMessengerスニペットを設定してください。匿名訪問者向けに軽量で安全な構成を維持するため、user属性は追加しないでください。

ステップ2:usersのためにJWTを生成し始める

業界標準のJWTライブラリを使い、Messenger API Secretを秘密鍵としてトークンを生成できます。秘密鍵は設定 > セキュリティ > Messengerで生成可能です。

注意: JWTトークンは各userセッションごとに一意に生成する必要があります。トークンにはuser_idなどの識別クレームを含め、Messenger API Secretで署名して正しいuserに安全に紐付けられるようにしてください。

インストールに適したコード例を得るために、バックエンドとフロントエンドのフレームワークを選択してください。

Node.jsの例はこちらです。

usersに関する追加属性(例:price_planやnumber_of_songs_added)を送信したい場合は、それらもJWTに追加してください。user_idは必須フィールドです。JWTペイロード内のフィールド名と属性は大文字小文字を区別します。例えば「user_id」は小文字の'i'で書く必要があり、「user_Id」では正しく識別できません。

注意: Finが生成したJWKでJWTトークンに署名する場合、subクレームはFinが割り当てたUser IDがデフォルトで使用され、一意のuser識別子として機能します。JWK機構を使うとsub値は固定されカスタマイズ不可で、互換性と誤設定防止を保証します。

ステップ3:MessengerスニペットにJWTを追加する

ログイン中のuser向けにMessengerを起動する際、署名済みJSONウェブトークンを提供し、Messengerペイロードのintercom_user_jwt属性に割り当てられます。あるいは、ログイン前にIntercom.setUserJwt(jwt)を使ってJWTトークンを割り当て、データの安全な帰属を行うことも可能です。

クライアント側設定例

  window.Intercom("boot", {
api_base: "https://api-iam.intercom.io",
app_id: "APP_ID_CODE",
intercom_user_jwt: <YOUR_USER_JWT_TOKEN>,
};

このJWTにはuserの任意のデータ属性を安全に含めることができます。有効なJWTが受信されると、ユーザーのブラウザにデフォルト7日間のセッションクッキーが作成されます。

MessengerセッションクッキーのTTLを制御するには、設定 > Fin Messenger > 一般の「Messengerを安全に保つ」ドロップダウンで最大値を設定できます。

ステップ4:属性の更新を無効にすることを確認する

Messenger APIのデータ属性に対して安全でない更新を有効にすると、Messenger経由のその属性の更新はすべて成功します。

JWTで安全に送信しているデータがある場合は、それらの属性に対する安全でないMessenger更新を無効にし、有効なJWT経由でのみ更新されるようにしてください。なお、この切り替えはbotでleadsから直接データを収集することは妨げません。

JWTで送信している属性には、この切り替えを有効にすることを推奨します。

ステップ5:ログアウト時にuserセッションを終了する

Fin Messengerは、あなたが所有する公開サイト(マーケティングサイト、ドキュメントサイト、開発者ハブなど)にインストールできます。ユーザーがログイン中に異なるサブドメイン間で会話の連続性を保つために、ユーザーのブラウザにクッキーを設定します。このクッキーは1週間で期限切れになります。

共有コンピュータやブラウザを他の人と使うユーザーは、クッキーが期限切れになるまで直近にログインしたユーザーの会話履歴を見ることができます。そのため、ユーザーのセッション終了時(手動または自動ログアウト時)にFin Messengerを適切にシャットダウンすることが非常に重要です。

Fin Messengerをシャットダウンする方法は以下の通りです:

  1. すでにIntercom JSスニペットまたは「boot」メソッドでユーザーのトラッキングを開始しています。

  2. ユーザーがFin Messengerからログアウトした(またはアプリによって自動ログアウトされた)場合、JavaScript APIのIntercom('shutdown');を呼び出してセッションを終了し、クッキーをクリアしてください。

最終ステップ:ワークスペースのMessengerセキュリティを強制する

統合がユーザーのJWTを正しく送信している場合、設定 > Fin Messenger > セキュリティでMessengerセキュリティをオンにして強制してください。これにより、Fin Messengerはワークスペースユーザーのリクエストに有効なJWTまたは有効なuser_hashのいずれかが必要になります。

注意:JWT認証はウェブとモバイルの両方でサポートされています。モバイルSDKはBring Your Own Channelアーキテクチャで準備完了かつ完全に機能しており、本記事の設定手順はウェブとモバイルの両方に適用されます。


トラブルシューティングガイダンス

インストールのデバッグに役立つ2つのツールがあります。1つは最近のエラーログを確認する方法、もう1つはトークンデバッガーです。

インストールログを確認する

設定 > Fin Messenger > セキュリティのステップ6でインストールログを確認できます。ここにはJWTインストールに関連するすべての失敗ログが表示されます。JWTが無効、期限切れなどのエラーが表示されます。「ログを見る」をクリックすると、リクエストID、タイムスタンプ、リファラー、ユーザーデータを含む完全なログが見られ、リクエスト失敗の原因を理解し自分のアプリに遡るのに役立ちます。

よくあるエラーメッセージ

  • HTTP 400 - "user_hashとintercom_user_jwtは同時に提供できません":リクエストにJWTとuser_hashの両方が含まれていました。顧客はどちらか一方を含めるべきで、両方は含めないでください。

  • HTTP 400 - “ペイロードにuser_idがありません”:すべてのJWTはペイロードにuser_idを含む必要があります。顧客が“email”を主な識別子と考える場合、emailの値をペイロードのuser_idとemailフィールドの両方に入れるべきです。

  • HTTP 400 - “無効なintercom_user_jwtペイロード”:JWTペイロードが無効です。顧客はペイロードが正しく形成され、エンコードされ、api_secret値を署名秘密鍵として使用したSHA256 HMACで署名されていることを確認してください。

  • HTTP 400 - “Intercom_user_jwtの有効期限切れ”:JWTの‘exp’が過去のタイムスタンプです。顧客は将来の有効期限を指定する必要があります。

  • HTTP 400 - “JWTのID不一致”:JWTに提供されたユーザーIDがアクティブなintercomセッションのクッキーに関連付けられたユーザーと一致しません。これは競合する2つのセッションを開始しようとしていることを示します。新しいユーザーを起動する前に必ずIntercom('shutdown')を呼び出してください。

  • HTTP 400 - "無効なintercom_user_jwt":有効なユーザーを正しく起動していることを確認してください。

  • JWTトークンの検証に失敗した場合(例えば、クレームの不一致や不適切な署名のため)、会話は自動的に閉じられ、問題のデバッグに役立つAPIエラーログにエラーが記録されます。

JWTデコーダー

デコーダーツールはJSON Web Tokenの検証も可能です。設定 > Messenger > セキュリティのサイドバーで見つけられます。

ツールで生成したユーザーJWTの有効性を確認できます。JWT生成に使用した秘密鍵を選択し、デコードをクリックしてください。

デコード後、JWTのペイロードからユーザー詳細、ヘッダー、有効か無効かの注記が表示されます。

この例では無効な秘密鍵を使い、user_idフィールドを含めていません。どちらも失敗の原因になります。


よくある質問

なぜJWTにuser_idが必要ですか?

ユーザーの主な識別子としてuser_idを提供する必要があります。これまではuser_idかemailのどちらかをサポートしていましたが、基本的なID検証で混乱が生じていました。emailしか識別子がない場合は、ペイロードのuser_idとemail属性の両方にemailアドレスを入れてください。

user_idがない非ログインユーザーにはどう設定すればいいですか?

Messengerセキュリティ機能は、ユーザーに一意のuser_idを提供することを要求します。leads用にMessengerを使う場合は識別できませんが、他の統合(REST API、CSVなど)でuser_idを持つユーザーがワークスペースにいる場合は、JWT Messengerセキュリティを有効にしてMessengerの不正起動を防ぐべきです。ログアウトした訪問者には、App IDのみでMessengerスクリプトを読み込み、ユーザーデータやJWTトークンを渡さない軽量版を使うことで認証なしで動作させられます。これにより使いやすさとシステム機能・データ整合性を両立できます。

要するに、ワークスペースに推測可能な識別子(email、user_id)を持つユーザーがいる場合はMessengerセキュリティを有効にしてください。ログイン済みと未ログインの両方をサポートする場合は、セキュリティと使いやすさの混合戦略を採用します。ログインユーザーにはJWT認証を使い機密情報を保護し、未ログイン訪問者にはユーザー固有のトークンやデータなしの簡易Messenger設定を許可します。

有効期限はどのように設定すべきですか?

Messenger起動ごとに新しいJWTを送信するため、トークンの有効期間はMessenger起動間の時間をサポートすれば十分です。アプリの動作に適した最短期間を選んでください。ウェブページが頻繁にリロードされる場合は短期間が望ましいですが、予期せぬ期限切れを防ぐため最低5分を推奨します。常にJWTに有効期限(exp)クレームを含めて、盗まれたトークンの影響を減らしセキュリティを確保してください。

どの署名アルゴリズムが使えますか?

以下をサポートしています:

  • HS256(SHA-256によるHMAC)。このアルゴリズムは共有秘密鍵でトークンを署名・検証し、トークン内のデータが改ざんされていないことを保証します。

  • RS256は非対称鍵ペアを使い、署名は秘密鍵、検証は公開鍵で行い、セキュリティ強化の代替手段を提供します。

  • JSON Web Key(JWK)構成は、Fin生成の鍵とシームレスに統合でき、トークン管理を効率化します。

user_hashとintercom_user_jwtの両方を送れますか?

いいえ、user_hashはJWTに置き換えられるべきなので、両方を同時に送信することはサポートしていません。ただし、移行中の顧客がuser_hashとintercom_user_jwtを交互に送信することは可能です。

JWTが有効で正常に動作しているかどうかはどう確認できますか?

上記のトラブルシューティングセクションを参照してください。

ワークスペースでJWTの必須化をどう強制しますか?

Messenger設定で強制トグルを有効にしてください。

どの属性を保護すべきですか?

すべての識別属性は保護マークを付け、可能な限りJWTで安全に送信してください。これにはemail、電話番号、顧客がユーザーレコードに保存する可能性のあるaccount_idが含まれます。属性は設定 > People Dataで確認できます。

FinがActionやWorkflowの重要部分で使用する属性は保護すべきで、悪意あるユーザーが値を上書きできないようにします。

JWT外でデータを送る場合はMessengerの更新を許可している必要がありますが、ユーザー自身がこのフィールドを更新できる可能性があることに注意してください。

    window.intercomSettings = {
app_id: <APP_ID_CODE>,
intercom_user_jwt: <TOKEN>,
unsigned_data_attribute: 'data'
};

ユーザーの操作中にセッションが期限切れたら?

クッキー期限切れ後にユーザーがMessengerで操作すると、ユーザー体験を損なわないように1時間の短期クッキーを新たに発行します。ユーザー体験への影響を防ぐため、クッキーのセッション期間はアプリのセッションタイムアウトに合わせることを推奨します。

なぜペイロード全体の署名を必須にしないのですか?

ユーザーがアプリケーションで操作を行っている間に、低精度のユーザーデータを送信する必要がある場合に対応するため、署名されていない属性の送信を許可しています。この機能が不要な場合は、すべてのUser Data Attributesを「Messengerの更新から保護」に設定し、署名済みペイロードのみを送信できます。

Messengerのシークレットキーはどのように管理・ローテーションしますか?

シークレットキーはワークスペースのMessengerセキュリティ設定で生成できます。

Identity Verificationはどうなりましたか?JWTがそれに代わるものですか?

Identity Verificationは、ユーザーリクエストがあなたの統合から送信されたことを識別するためにHMACユーザーハッシュを使用するMessenger Securityの以前のバージョンです。

ユーザーハッシュは引き続き受け入れられますが、より多くのセキュリティ利点があるため、すべての顧客にJWTへのアップグレードを強く推奨します。Identity Verificationは今後更新されません。


JWTページからIdentity Verificationのインストールを管理する必要がある場合は、引き続き可能です。手順はJWT設定に合わせて更新されており、変更を行う場合はJWTへの移行を強く推奨しますが、機能を無効にしたりMessenger APIのシークレットキーをローテーションしたりする必要がある場合は、設定 > セキュリティ > Messengerから引き続き実行できます。

JWTに会社データを含めて、ユーザーを会社に関連付けることはできますか?

はい。JWTペイロードにcompany_idやその他の会社属性を含めて、ユーザーを会社に関連付けてください。これにより、起動時に会社が自動的に作成・関連付けされ、追加の遅延は発生しません。

重要:JWTの外で渡された会社データ(例えば、Intercom('boot')呼び出しのcompanyオブジェクトとして)は、JWTが存在する場合は無視されます。会社は更新されず、会社のlast_seen値も更新されません。会社データを正しく更新するには、JWTペイロードに含めてください。

こちらの回答で解決しましたか?