ZAF の Secure Settings を使って認証方式別に疎通確認してみた

ZAF の Secure Settings を使って認証方式別に疎通確認してみた

ZAF の Secure Settings では、secure 値は JavaScript に返らず、プレースホルダは文字列置換のみです。この仕組みを踏まえ、認証付き API へ複数の認証方式で疎通確認した結果と、Basic 認証の正しい繋ぎ方をまとめます。
2026.07.11

はじめに

先方から提供された Basic 認証付きのエンドポイントに、ZAF (Zendesk Apps Framework) アプリから繋ぐ場面がありました。最初は認証が 401 で通らず少し戸惑ったのですが、原因は ZAF の Secure Settings の仕組みを私が誤解していたことでした。

secure 設定の値は JavaScript に返りません。プレースホルダは文字列置換のみで、base64 化まではしません。この 2 点を押さえると、認証付き API へスムーズに繋げられます。

本記事では、認証付き API に ZAF から複数の認証方式で疎通確認した結果と、そこから得たノウハウをまとめます。

対象読者

  • ZAF アプリから認証付きの外部 API に繋ぎたい方
  • Secure Settings を使っているのに認証が通らず悩んでいる方

参考

起きた問題

最初は、認証情報のユーザー名とパスワードを別々の設定として持ち、フロントエンドで Authorization ヘッダを組み立てていました。'Basic ' + base64(user + ':' + password) のような書き方です。このとき client.requestsecure オプションは付けていませんでした。

これはローカルでは動作しました。ところがテナントへデプロイし、secure 設定に実値を入れたところ、認証付き API が 401 になり「認証情報を確認してください」というエラーが消えなくなりました。また、サーバが返す WWW-Authenticate にブラウザが反応し、ネイティブの Basic 認証ダイアログが出ました。

Basic 認証ダイアログ

原因調査

公式ドキュメントを読み直して、原因が分かりました。secure: true を宣言した設定値は、client.metadata() 経由でフロントエンドには返りません。

正しい方法は、secure 値をリクエストに乗せるのに、ヘッダに {{setting.NAME}} というプレースホルダを書き、client.requestsecure を true にすることでした。こうすることで Zendesk のプロキシがサーバ側で実値に置換します。フロントエンドで base64 を組み立てる必要はない、むしろ組み立ててはいけないということになります。

疎通確認

認証エンドポイントに httpbingo.org を使い、ZAF の client.request() で 5 通りの認証方式を試しました。結果は次のとおりです。

# 認証方式 結果 分かったこと
1 Basic・自前 base64 を 1 つの secure 値 成功 (200) 事前に base64 化して 1 設定に入れれば通る
2 Basic・basic_auth.token 成功 (200) プロキシが base64 するので自前変換は不要
3 Bearer トークン 成功 (200) プレースホルダ + secure でそのまま通る
4 API キー ヘッダ 成功 (200) scope 未指定でも通る・明示は推奨
5 フロントエンドで base64 生成 失敗 (401) 置換前に base64 され、認証ダイアログも出る

結果1
サイドバーアプリを使用した疎通確認。ケース 1~3

結果2
サイドバーアプリを使用した疎通確認。ケース 3~5

ケース 1 は、user:passwd を自分で base64 化した値を 1 つの secure 設定に入れ、ヘッダにはプレースホルダだけを書く方式です。

// Basic 認証・自前で base64 化した値を 1 つの secure 設定に入れる
client.request({
  url: 'https://httpbingo.org/basic-auth/user/passwd',
  type: 'GET',
  secure: true,
  headers: { Authorization: 'Basic {{setting.basicManualB64}}' }
});

ケース 2 は、公式が用意する basic_auth の仕組みです。ユーザー名とパスワードを渡し、ヘッダには {{basic_auth.token}} を書くと、プロキシが連結して base64 化します。自分で base64 化する必要がありません。

// Basic 認証・basic_auth.token 方式・プロキシが base64 化する
client.request({
  url: 'https://httpbingo.org/basic-auth/user/passwd',
  type: 'GET',
  basic_auth: { username: 'user', password: '{{setting.basicPassword}}' },
  secure: true,
  headers: { Authorization: 'Basic {{basic_auth.token}}' }
});

注目したいのはケース 4 です。httpbingo の /headers はリクエストヘッダをそのまま返すため、プロキシがサーバ側で挿入した後の実値が見えます。このエコーに Zendesk プロキシの痕跡が現れ、リクエストがフロントエンドから直接ではなく、プロキシ経由でサーバ側から送られていることが分かります。

X-Api-Key にはプロキシが挿入した実値が入り、ViaX-Zendesk-* に Zendesk プロキシの痕跡が出ています。

{
  "headers": {
    "X-Api-Key": ["(プロキシが挿入した実値)"],
    "Via": ["zorg, 1.1 fly.io, 1.1 fly.io"],
    "X-Zendesk-User-Role": ["admin"],
    "X-Requested-With": ["XMLHttpRequest"],
    "Zendesk-Internet-Path": ["cloudflare"]
  }
}

一方で、ブラウザの開発者ツールの Network タブでは、同じヘッダが {{setting.apiKey}} というプレースホルダのまま表示されます。実値はプロキシより先にしか出ない、ということが確かめられます。

ケース 4・Network タブではプレースホルダのまま表示される
ブラウザにはプレースホルダしか出ず、実値はサーバ側で挿入される

なぜフロントエンドで base64 化してはいけないのか

ケース 5 は、最初に私が書いていた実装を再現したものです。フロントエンドで btoa() を使い、プレースホルダを base64 化してからヘッダに入れます。

// 避けたい書き方・プレースホルダを btoa で base64 化してしまう
client.request({
  url: 'https://httpbingo.org/basic-auth/user/passwd',
  type: 'GET',
  secure: true,
  headers: { Authorization: 'Basic ' + btoa('{{setting.basicManualB64}}') }
});

btoa() はプロキシの置換より前に走るため、プレースホルダの文字列そのものが base64 化されて送られます。プロキシが探す {{setting.NAME}} の形が壊れるので置換されず、誤った認証情報のまま届いて 401 になります。

さらに、この 401 が WWW-Authenticate を伴うため、client.request 経由でもブラウザのネイティブ Basic 認証ダイアログが出ます。認証が通らないうえに、ユーザーに認証ダイアログを見せてしまいます。

ケース 5・401 でブラウザの Basic 認証ダイアログが出る
フロントエンドで base64 化すると認証が通らず、ダイアログまで出てしまう

分かったこと

疎通確認から得たノウハウは次のとおりです。

secure 値はフロントエンドに返らないため、認証情報をフロントエンドで組み立てる設計は避けます。Basic 認証は、自分で base64 化した値を 1 つの secure 設定に入れるか、basic_auth.token 方式でプロキシに base64 化させます。Bearer や API キーは、プレースホルダ + secure でそのまま通ります。

運用面では、scope を明示指定するのが推奨されます。指定しないと secure 値が意図しない scope で使われる恐れがあります。また、secure 設定は保存後に Admin Center の入力欄が空表示になりますが、保存されていないわけではありません。

secure 設定
管理センター→Zendesk Supportアプリ→作成したアプリ を選択し、secure 設定を入力して更新する

空表示
更新後、入力欄は空表示になる

まとめ

ZAF の Secure Settings は、secure 値がフロントエンドに返らず、プレースホルダは文字列置換のみという設計です。この 2 点を押さえれば、認証付き API へ繋げられます。Basic 認証は自分で base64 化するか basic_auth.token 方式を使うというのが疎通確認で確かめられました。同じところで戸惑っている方の参考になれば幸いです。


Zendeskの導入支援ならクラスメソッドへ

クラスメソッドはZendeskのライセンス販売パートナーです。Zendesk導入にあたって、設定代行、オペレーターや管理者向けのトレーニング、独自のアプリ開発、データ移行など、様々なサービスをご提供しております。既に導入済みのお客様に対してもご支援できますので、まずはお気軽にご相談ください。

Zendeskの導入支援の詳細を見る

この記事をシェアする

関連記事