FileMakerのクイック検索とデフォルト言語

FileMaker 2023 (Ver.20.3.2.201) で不可解な動作がありました。なぜか、見え見えの検索条件を指定しても、クイック検索で検索できないのです。原因は、そのフィールドのオプション設定にあるデフォルト言語をUnicodeにしていたからです。通常「日本語」なので、何か設定をしてしまったのでしょうけど、「日本語」だとクイック検索できて、「Unicode」だと検索できないってなんか変な気がします。

ビデオを見ていただくとわかるように(外を歩く子供達の声が聞こえるけど無視して〜)、最初の検索で、「日本」では検索できるけど「大学」では検索ができないです。「病院」も同様に検索できません。検索できる文字とできない文字があるようです。このフィールドのデフォルト言語をUnicodeにしてありますが、それを「日本語」に変えるとちゃんと検索できています。

まあ、Unicodeにするなということだと思いますけど、デフォルト言語を「デフォルト」にしても、Unicodeと同様に、「病院」などの検索ができなくなりますね。これ、バグなんだろうか? あるいは有名な話?

simplesamlphpのIdPでGoogle OAuth2認証を実行する

PHPでのSAML認証ライブラリであるsimplesamlphpは、PHPでSAML認証を行う場合にはほぼ一択となる選択肢です。これを利用してIdPを構築する方法は、https://blog.msyk.net/?p=1566 で紹介しました。本項目は、別掲の記事で紹介したIdPが存在する状態で、Google OAuth2、すなわちGoogleのアカウントでSAML認証を行えるようになるまでを紹介します。

とりあえずセットアップ方法とテスト方法は残しておかないといけないと思いつつ、まずは記事を書いたのです。INTER-MediatorでのGoogleアカウントでの認証は成功してはいませんでした。そして1日経過し、ふと疑問に思った事があります。simplesamlphpの追加モジュールとしてcirrusidentity/simplesamlphp-module-authoauth2を使うことにしています。このモジュールは、OAuth2の汎用モジュールなので、Google向けということではありません。さて、このモジュールは、IdPに必要なのか、SPに必要なのか、どちらなのでしょうか? このことは、ライブラリのインストールのページにも書いていません。当たり前のことなのかな?

以下の方法で、IdPにまずはインストールして設定を追加して、リダイレクトURLはIdP側にしたのですが、認証されている状態になりませんでした。そこで、全く同じようにSP側にもモジュールを追加し、リダイレクトURLをSP側にしましたが、なんと、全く同じ結果になりました。どちらでもいいのかもしれません。どちらでやっても同じ結果になったので、どっちが正しいのかという結論はとりあえずは出ていません。しかし、OAuth2の認証サーバがすでにあるという前提を考えれば、SPだけを用意してそれを利用する方が明らかに作業は少なくて済みます。ということは、SP側にモジュールを追加して運用するのが正しいような気がします。IdPに登録したユーザで認証する結果をみていると、一旦IdPに行ってログインパネルを出して、そこから、SP内部へリダイレクトして認証結果が伝わってくるように思えるので、やはりそのこともあって、SPへモジュールを追加するのが正しいように思います。

Googleのプロジェクトから認証情報を得る

SimpleSAMLphpの設定の前に、GoogleからクライアントIDとシークレットを取得します。その方法はあちらこちらのサイトで記載されていますので、例えば、Shinonome Tech BlogのOAuth 2.0 を使用してGoogle API にアクセスする方法 に記載された「1.Google API ConsoleでOAuth2.0の認証情報を取得」の作業を行なってクライアントIDとシークレットを取得します。以下、それぞれ、MYCLIENTID、MYCLIENTSECRETと記述します。つまり、これらのキーワードが登場したら、Google Developer Consoleで取得した実際の値に置き換えて設定等を行なってください。なお、「承認済みのリダイレクトURI」には、以下のURLを指定します。module.php以下のパスは常に同じですが、それ以前は実際にSPのサイトをどのようにセットアップしたかに依存します。

https://demo.inter-mediator.com/simplesaml/module.php/authoauth2/linkback.php

なお、実際のSPは「アプリケーション内のsimplesamlphp」でもあるので、エイリアスを使わないパスだとこのようになります。いずれにしても、Google側への登録と、後で説明する認証画面を出すためのURLの両方に、同一のリダイレクトURLを指定する必要があります。

https://demo.inter-mediator.com/saml-trial/lib/src/INTER-Mediator/vendor/simplesamlphp/simplesamlphp/public/module.php/authoauth2/linkback.php

SPにモジュールを追加する

SPで使用するモジュールは、https://github.com/cirrusidentity/simplesamlphp-module-authoauth2.git です。simplesamlphp自体にはGoogle OAuth2に対応した処理を実行できる素材はないので、外部から追加します。composer.jsonに組み込むか、あるいは次ようなコマンドで追加でインストールを行います。

composer require cirrusidentity/simplesamlphp-module-authoauth2

続いて、SP側のsimplesamlphpのconfig/config.phpファイルを修正します。まず、この先で、SAML認証結果を利用するアプリケーションのドメインを追加します。既定値では[]になっていますが、OAuth2のモジュールはこの設定を見ているようです。

'trusted.url.domains' => ['demo.inter-mediator.com'],

そして、OAuth2モジュールを利用可能にします。IdPとしてセットアップするときに値を変更した配列に、1行加えます。

'module.enable' => [
    'exampleauth' => true,
    'core' => true,
    'admin' => true,
    'saml' => true,
    'authoauth2' => true,
],

次に、config/authsources.phpに次の指定を加えます。’default-sp’などと同じ階層にキーとして’google’を指定し、値として配列を指定します。MYCLIENTID、MYCLIENTSECRETは実際に取得した値にもちろん置き換えて指定します。

'google' => [
   'authoauth2:OAuth2',
   'template' => 'GoogleOIDC',
   'clientId' => 'MYCLIENTID',
   'clientSecret' => 'MYCLIENTSECRET'
],

SP側の設定はとりあえずこれでOKのようです。SPの管理画面に、authoauth2モジュールが稼働していることが見えています。

なお、Testのところに「google」というリンクが出ており、クリックするとGoogleのページを表示しますが、認証処理までには至りません。リダイレクトのURLが設定されていないというようなメッセージが見えます。

認証プロセスを通して見る

ここで実際に使用しているアプリケーションのURLは「https://demo.inter-mediator.com/saml-trial/chat.html」です。このURLと最初の方でGoogle Consoleで指定したリダイレクトURL「https://demo.inter-mediator.com/simplesaml/module.php/authoauth2/linkback.php」がこの後必要になります。これらのURLに加えて、MYCLIENTIDを含め、以下のURLの文字列をエディタ上などで整えます。URLEncodingをしてもいいのですが、問題ある文字列はないので、そのままこの文字列に置き換えて利用してもいいでしょう。そして、このURLをブラウザのアドレス欄に貼り付けて、Enterキーを押し、GoogleのOAuth2の認証プロセスに入ります。なお、URLの細かい点では別の機会に改めてきちんと処理すると言うことにして、まずは動く状態にしたいと思います。

https://accounts.google.com/o/oauth2/v2/auth?response_type=code&client_id=MYCLIENTID&scope=openid%20email&redirect_uri=リダイレクトURL&state=authoauth2|security_token%3D333344445555%26url%3DアプリケーションURL&nonce=0394852-3190485-2490358&hd=gmail.com

stateはちょっと適当にしていますが、「authoauth2|」で始まっていないと行けないのは、このモジュールでの実装です。また、stateの中に「url=アプリケーションURL」と言う記述があって、そこが後から効いてきます。

ちなみに、OAuth2に対応したサイト等では、認証がなされていない場合に、GoogleやFacebookの認証プロセスに入るボタンを提供するかと思います。その場合、「Google」ボタンをクリックすると、上記のURLにリンクするような作りになっているはずです。FacebookならFacebookの認証システムへのURLにパラメータを設定してジャンプするようになっています。

URLをブラウザのアドレス欄に入れると、Googleの認証の画面になります。状況は人によって違うのでしょうけど、いずれにしても、Googleの認証の画面になって、ログインしていない場合はユーザ名とパスワードの入力を行ないます。

Googleの認証ページから、アプリケーションURLに指定したURLにリダイレクトされます。

実のところ「よしOK!」とは行きません。INTER-MediatorのSAML対応では、このままでは認証を継続させる事ができないので、これからチェックしないと行けないのですが、アプリケーションURLに対しては、それよりも先にリダイレクトURLにアクセスし、さらにそこからアプリケーションURLへリダイレクトされているようで、GETメソッドで何のパラメータもありません。SAMLのクッキーがHTTP Onlyで乗ってくるだけのようです。ちなみに、SAML認証が成功すると、SimpleSAMLとSimpleSAMLAuthTokenという2つのクッキーが入るのですが、現状、IdP/SPいずれの側を利用しても、前者のクッキーしか入らず、後者は入ってこないのです。

(続報:2024-3-9)その後、色々やってみたのですが、認証が成功した状態のクッキーになりません。と言うことで、コードを読みました。simplesamlphp-module-authoauth2には認証後に返ってくるURL(linkback.phpで終わるもの)が記載されており、実際にそのリダイレクトURIが呼び出されています。そこをチェックすると、前述の「https://accounts.google.com/o/oauth2/v2/auth」に対するstateパラメータの値は、次のようになるはずです。色々試しているうちに、セッションデータが落ちてきたのでわかったことです。

state=authoauth2|_796bed184adf107c10c0faf60c658c7da54d2b0972:アプリケーションURL

最初は「authoauth2|」である必要があります。リダイレクトされた最初の段階でチェックしています。続いて、|より後の文字列について、:で区切って、最初をid、最初の:以降をマージしてurlとしています。エラーがあると、そのurlにリダイレクトがします。セッションのデータが何かのきっかけで落ちてきた時に、そこからデータが取り出せるとしたら、|と最初の:の間は上記のコードか、もしくは「_eff7a14ba6adc55b6cd2f08b0399b747ed3ac9844e」である必要があります。このコード、ランダムに充てられている可能性もありますが、このデータで数回セッションデータが得られた後、セッションデータはほぼ空っぽのものばかりになってしまっていました。それで、SPの管理ページのログインテストを利用して、一度認証した状態にしておいて、アプリケーションを動かすと、今度は、セッションデータは何か大量に乗っかってきています。SimpleSAMLAuthTokenクッキーも来ました。しかし、その時のstateの|より後にくるべきコードは違うものでした。やはりランダムでした。このstateは最初にaccounts.google.comを呼び出すときに引数に指定しないといけないと言うことは、開発者が指定しないといけないと考えられますが、それを得る方法はわかりません。あるいは指定したコードが乗ってくるということなのかな?もうちょっとコードを追ってみようと思います。と言うことで、ここまでは行けました。ちょっとだけ進歩したかな。そうこうしているうちに、SimpleSAMLphpのVer.2.2.0が出ましたね。セッションのなかに、「アップデートしろー!」って情報がどっさり。

PHPのIntlDateFormater, 大晦日にいきなり来年になる

PHPにIntlDateFormaterというクラスがありますが、これを使って「今日」を生成している箇所で、本日2023年大晦日にもかかわらず、2024-12-31と出てきました。以下のSandboxにコードを貼っておきます。これはやっぱりバグでしょうね。DateTimeのformatならきちんと2023と出ています。

https://onlinephp.io/c/1cbcf

(追記)バグレポートをしたら、フォーマット文字列はYではなく、yかyyyyを使えと教えてもらいました。なるほど、Yの意味(year of “Week of Year”)がやっとわかった。

FileMakerからPowerShellスクリプト実行

FileMakerのスクリプト内でPowerShellを動かしたくなったのですが、概ねうまく行ったのでノウハウを忘れないうちにブログにしておきます。もちろん、Windows版です。PowerShellで動かしたいのは画面ショットです。こちらのサイト「Windowsのコマンドラインからスクリーンショットを撮る(PowerShell)」にそのまま使えるスクリプトがあったので使わせてもらいました。ありがとうございます。また、FileMakerのスクリプトからシェルスクリプトを稼働する方法は、「Claris Community | Powershell script not working」に記載があります。

これで終わるかといえば、それだけならブックマークに忘れないように覚えさせておくだけで終わってしまいます。まず、通常は、Windowsでは、いきなりシェルスクリプトはセキュリティ的な理由で動かせないようになっています。そこで、以下のようなコマンドを、PowerShell等で入れておく必要があります。これで実行権限が与えられます。そのユーザでログインしている間は再起動してもシェルスクリプトは動きます。「Bypass」はなんでも動かすためのものなので、オンラインからの素材は検疫(デジタル署名の確認を)する「RemoteSigned」という設定の方が少しはマシかもしれません。

Set-ExecutionPolicy -ExecutionPolicy Bypass -Scope CurrentUser

これが実行されていないと全くスクリプトは動きません。

続いて、前述のClaris Communityのやり取りにもあるのですが、Quote関数を使うことが重要です。スクリプトを実行するためには、「イベントを送信」スクリプトステップを利用し、「送信イベント」は「ファイル/アプリケーションを開く」を選択しておきます。この選択肢は、FileMakerをWindows版で動かさないと出てきません。そして、「計算」を選択して、コマンドを送り込みます。ここで、あるシェルスクリプトにファイル名の引数を付与してPowerShellで実行する場合はこのような式になるかと思います。変数に期待する値などの状況も含めて書きます。

仮定
$scriptPath ← "C:/Users/msyk/myscript.ps1" // シェスルクリプトへの絶対パス
$targetPath ← "C:/Users/msyk/data.bmp" // スクリプトの引数に渡すファイルパス

「イベントを送信」スクリプトステップの「計算」の式:
"powershell.exe -command " & 
Quote(Quote($scriptPath) & " " &Quote($targetPath))

-commandパラメータの引数は、単一の文字列で「コマンドライン」を指定します。ですが、コマンド中に”があると、そこでパラメータが終わっているとシェルは思ってしまうので、全体をQuoteで囲みます。Quoteは全体をQuoteで囲むだけでなく、文字列内部の”は、\”のようにエスケープします。ただ、元のコマンド自体もパスであり、スペースが入る可能性を考えると、やっぱりQuoteします。コマンドラインとしてうまく値を引き渡すには、このQuoteのQuoteで大体うまくいくことがわかりました。

まず、ここで、Get関数を使えやと思うところかと思いますが、FileMakerのGet (ドキュメント)等は、「/C:/Users/msyk/Documents/」のように、頭に/がついてしまいますが、それだとPowerShellは正しくパスとして認識しません。C:/Users/…のように記述されていないといけないようです。ということで、Get関数の結果を文字列処理するか、いっそのこと、絶対パスを文字列で書くか、まあ、その辺りはソリューションに応じて頑張ってください。

もう1つ、ファイル名に使ってはいけない文字列があることを忘れないでください(例えば、こちらのサイトで一覧されています)。|や/はファイル名としては使えません。これらは、Substitute関数で置き換えてから、PowerShell実行スクリプトの引数に与えます。また、ファイル名として使えない名前(COM1など)もあるので、何かで取得した名前をファイル名として利用する場合にはデータを俯瞰して対策は必要になります。

SimpleSAMLphp Ver.2を使ってみる(3)

(1)はIdPの起動、(2)はIdPの管理画面のチェックと進みました。ということで続いてSPです。ここでのSPはINTER-Mediatorで稼働しているという前提で話をします。状況としては次のようなものです。

  • 証明書を発行済みのドメインdemo.inter-mediator.com内で稼働する。DocumentRootは/var/www/demo_im_com
  • DocumentRootにsaml-trialディレクトリを作り、そこに、ページファイルchat.html、定義ファイルchat.phpを定義した
  • INTER-Mediatorは、saml-trial/lib/srcにgit cloneでインストールして、composerで必要なライブラリをインストール
  • 結果的に、SimpleSAMLphpのレポジトリのルートは、DocumenRoot以下、saml-trial/lib/src/INTER-Mediator/vendor/simplesamlphp/simplesamlphp となる
  • 設定ファイルのparams.phpは、saml-trial/lib/src/params.phpとする
  • demo.inter-mediator.comをホストしているApache2のsiteファイルでは、以下のように、/simplesamlへのエイリアスを作成する(Aliasの行は1行で記述)
<VirtualHost *:443>
    ServerAdmin info@inter-mediator.org
    DocumentRoot /var/www/demo_im_com
    ServerName demo.inter-mediator.com
Alias /simplesaml "/var/www/demo_im_com/saml-trial/lib/src/INTER-Mediator/vendor/simplesamlphp/simplesamlphp/public"

いきなり動くかなと確かめてみたら、ダメでした。composerの扱いをちゃんとやらないといけません。ここでは、composer.jsonのsimplesamlphp/simplesamlphpの値を”2.0.4″とバージョンをしっかり入れるようにしてみました。INTER-Mediatorの場合、composer clearnでライブラリを消して、composer update, composer installの順でコマンドを入れれば良いでしょう。

simplesamlphpの管理ページは、前回にも紹介したように、赤いヘッダなどがついたもので、CSSやスタイルシート、画像などが提供されています。ブラウザでパスを見る限りは、/simplesaml/assets/base…となっているので、レポジトリのpulic/assetsを見るのですが、空です。どうやら、assets以下の内容は、simplesamlphp/simplesamlphp-assets-baseという別のパッケージにあるようで、これが読み込まれていません。この別パッケージをassets以下に展開するには、composer installが必要なようで、結果的にupdateとinstallは両方行う必要があるようです。

設定ファイルの記述

これまでのセットアップを行うと、SimpleSAMLphpのSP自体は、パスがちょっと長いですが、/var/www/demo_im_com/saml-trial/lib/src/INTER-Mediator/vendor/simplesamlphp/simplesamlphpに存在することになります。以下のこのパスを「SPのルート」と記載します。このディレクトリの、configに設定ファイル、metadataにメタデータファイル、certに証明書類を入れるのが基本です。以下、参考にコマンドを記述しますが、INTER-Mediatorではもう少し手軽にする方法を用意していて、近々、これをSimpleSAMLphp Ver.2向けに更新する予定です。

まず、通信暗号化のための証明書を作ります。この証明書はサイトのTLSのための証明書を使ってもよく、実際には案件ではそのようにしましたが、SimpleSAMLphpのサイトの説明では、10年期限の自己署名証明書を作っています。サイトの証明書はつまり「自己署名だとダメかも」と思って使っていたわけですが、本家の説明がいきなり自己署名なので、単に暗号化のためだけに使っているということですね。opensslコマンドの後に属性などを入力しますが、(1)のIdPのところと同様適当に入れればいいかと思います。-outと-keyoutの後のファイル名も適当に指定します。

cd cert
openssl req -newkey rsa:3072 -new -x509 -days 3652 -nodes -out sp.crt -keyout sp.pem

SPのルート以下、configディレクトリには、元からあるconfig.php.distからコピーしたconfig.phpを用意します。そして、その内容を変更します。ポイントは以下の点です。baseurlpathは、SPのルートのpublicを参照するようにします。以前はwwwを参照していましたが、Ver.2で変わっています。残り3つの設定は、IdPと同様ですので、(1)の記事を参照してください。

'baseurlpath' => 'saml-trial/lib/src/INTER-Mediator/vendor/simplesamlphp/simplesamlphp/public/',
'technicalcontact_email' => 'your_email',
'secretsalt' => 'your_salt',
'auth.adminpassword' => 'your_admin_pass',

SPのルート以下、configディレクトリには、元からあるauthsources.php.distからコピーしたauthsources.phpを用意します。以下のように、default-spキーの配列の要素に、certificateとprivatekeyのエントリーを用意して、ここで作成したキーファイルと証明書ファイルを指定します。そして、entityIDをサイトのドメインに設定しておきます。

'default-sp' => [
  'saml:SP',
  'certificate' => 'sp.crt',
  'privatekey' => 'sp.pem',

   // The entity ID of this SP.
   'entityID' => 'https://demo.inter-mediator.com/',
   :

SPのルート以下、metadataディレクトリには、元からあるsaml20-idp-remote.php.distからコピーしたsaml20-idp-remote.phpを用意します。このファイルの最後(とはいえ、中身は短いコメントがあるのみ)に、IdPの管理ページからコピーした配列をコピーしておきます。

SPの管理ページからメタデータを取得

ということで、インストールに少しハマってしまいましたが、なんとか動きました。一応のルートは、https://demo.inter-mediator.com/simplesaml ですが、こちらは「ようこそ」と出るだけです。SPの管理ページに行くには、このURLの後にadminをつけた、https://demo.inter-mediator.com/simplesaml/admin にアクセスします。そして、config.phpで指定したパスワードを入力して、管理者として認証します。

設定のページは諸々確認できますが、ModulesのところでIdPとしては稼働していないことなどが分かります。

Testのタブでdefault-spのリンクをクリックすると、次のような画面が見えており、登録したIdPを認識していることが分かります。ただ、ここで「選択」をクリックするとエラーになるので、まだ何か問題なのかもしれません。

連携のところで、「V」の部分をクリックすると、メタデータが表示されます。このメタデータを、IdPに登録します。IdPがSimpleSAMLphpなら、metadata/saml20-sp-remote.phpファイルに追記することになります。

認証できています

それでは実際にIdPで認証したユーザで、INTER-Mediatorのアプリケーションを使ってみます。通常、ログインパネルが出てくるとこが、IdPというか、SPの画面に行きます。ここでは、まず、IdPを選択します。

すると、ログインパネルが出てきます。こちらはドメインを見ればわかるように、IdP側に切り替わっています。ここでは、テストユーザのuser01でログんを試みます。

無事にログインができ、メッセージが見えています。

ちなみに、SAML-tracerを使って追っかけてみました。チャットのアプリケーションのURL(https://demo.inter-mediator.com/saml-trial/chat.html)をブラウザに入れると、何度かリダイレクトされて、IdPの側の認証ダイアログが表示されます。そこまでのトレースは以下の通りです。

続いて、正しいユーザとパスワードを入力して、IdPにポストしますが、その後、アプリケーションのURLにリダイレクトされています。この時は、認証が通っているので、アプリケーション側でも、認証が通った後の処理をして、ページが構築されています。

ということで、SimpleSAMLphp Ver.2.0.4でも動くことを確認しましたが、途中ちょっとハマった理由は、すでにVer.3の作業に入っていることに気づかず、dev-masterで作業したら、色々思った通りに動かなかったのでした。Packagistのサイトを見て、あ、Ver.3.0.0になっていると気づき、Ver.2.0.4で通るようにやり直して稼働を確認できたという次第です。ちゃんとチェックしようねってことですね。

SimpleSAMLphp Ver.2を使ってみる(2)

前の記事では、テスト用のIdPを起動するところまでを説明しました。Ver.2ではIdPの管理画面も新しくなっているので、続いてその管理画面に何が出ているかを確認しましょう。

まず、画面上部のタブ「設定」のページです。最初にSimpleSAMLphpのインストール場所やバージョンが見えています。正しく、Ver.2.0.4がインストールされていると判断できるでしょう。そして、インストールされているモジュールや動作チェックなどがあります。Ver.2になった変更点として、プラグイン的に必要な機能は追加するようになったと記載があり、必要な素材が全部入っている状態ではありません。必要な機能があるのなどはこの画面などでのチェックも必要かもしれません。

前の画面のDetailsにある「Information on your PHP installation」のリンクは、phpinfo()関数を動かした結果を表示します。「ホストネームやポート、プロトコルを診断」は次のような画面を表示します。サーバがきちんと動くようなら、特に確認は不要かもしれません。

「Test」のタブでは、admin、default-sp、example-userpassの3つのリンクがあります。まず、adminは次のように、管理者ログインに関する情報が見えています。

「default-sp」をクリックしても「No identity providers found. Cannot continue.」と出るだけです。これは正しい状態なのか、追々調べます。

example-userpassをクリックすると、次のようにログインパネルが出て、ログインの検証が可能です。ここで、config/authsource.phpで定義したユーザとパスワードを入れてログインをしてみます。

正しいユーザ名とパスワードを入れれば認証が行われて、その時に得られる属性についても表示されます。

ページ上部の「連携」をクリックすると、次のような表示が見えます。SPが2つになってしまっていますが、idpのドメイン名を設定した側を利用するものとして想定します。ここでは、中央付近に見えているボックスの下部にある「V」部分をクリックします。

V部分をクリックすると、表示が開いて、IdPのメタデータが表示されます。上部が一般的なXMLによる記述で、下部がSimpleSAMLphpで利用できるPHPの配列形式のメタデータです。ともかく、SPとの連携の時のデータは取り出しができるようです。

以上のように、IdPの管理画面としては、以前より少しは機能が増えたものの、SPの登録などはないようなので、やはり基本は設定ファイルを修正するということになるでしょう?認証可能かどうかやインストール状態などの動作チェック等にはある程度は利用できそうです。

SimpleSAMLphp Ver.2を使ってみる(1)

PHPでSAML認証を実現するライブラリ、SimpleSAMLphpが、2023年からVer.2となりました。SAML 2.0に対応するのは以前から、つまり、SimpleSAMLphp Ver.1でもSAML 2.0に対応していましたが、どちらのバージョンも「2」になったということです。バージョン記述がややこしいですが、まあ、これを読んでいる方は慣れているかと思いますので、先に進みます。

この記事は2023 7/1に最初に記述しましたが、状況が変わりつつあるのとノウハウが少し溜まったこともあって、2024/3/2までに追記を何度か行なっています。

INTER-MediatorはSimpleSAMLphpベースでSAML対応しています(勉強会での発表ビデオはこちらです)。SAMLというか、Shibboleth認証の案件を実際に行ったこともあります。ということで、SimpleSAMLphp Ver.2は早めにチェックしようと思いつつ、今になってしまいました。

SimpleSAMLphp Ver.2になっての違いはこちらのページに記載されています。かいつまんで説明すると、Shibboleth 1.3、SAML 1.1にはもう対応しないということで、SAML 2.0のみ対応となっています。ということは、Shibboleth案件は、Ver.1.19.xあたりで作業する必要があるということになります。設定ファイル名は変わっていないものの、「作り直したほうがいい」となっていますので、手順を含めて、引き続いてそのあたりは説明したいと思います。それから、いくつかの重要なパスも変わっています。これも説明で紹介します。

INTER-MediatorのSAMLのテストは、SimpleSAMLphpによるIdPと、SimpleSAMLphpによるSPを使って行うようにセットアップをしてあるのですが、改めて、この環境を構築し直しを始めました。その記録をブログにつけていこうと思います。IdPには、テスト用のアカウントをいくつか記録する程度で、そこから別の認証サービスを使うまではとりあえずは考えていません。

テスト環境ですが、Ubuntu Server 22.0.4 LTSです。よって、PHPは8.1です。普通に、Apache2、PHPとモジュールをインストールしました。INTER-Mediatorをインストールする以外には、PHPのSOAPモジュールを追加するだけで大丈夫でした。 テスト用のアプリケーションも当然ながらINTER-Mediatorで作ってあるのですが、SimpleSAMLphpのVer.1とVer.2の相互運用も考えないといけないのかなとも考えられます。

さて、数年前に一生懸命検証をした時の1つの結論は、「ちゃんとドメインを切って、正しい証明書をセットアップしたサイト」にするということです。その時の設定はまだあって、IdP用にidp.inter-mediator.com、アプリケーションとSPはdemo.inter-mediator.com/saml-trialにしました。いずれも、Let’s Encryptではありますが、それぞれ有効な証明書が動き、通信はすべてHTTPSで動くという状態になっています。

IdPサイトの構築

IdPのサイトは、SimpleSAMLphpのコードをそのまま使って構築します。Ubuntuなので、/var/www以下に、例えば、以下ようなコマンドで、コードを取り出します。バージョンごとにタグがあるので、Ver.2系列の最新版である2.1.4をインストールすることにします。そして、composerを動かして、必要なライブラリのインストールを行います。

cd /var/www
git clone https://github.com/simplesamlphp/simplesamlphp simplesaml-idp
cd simplesaml-idp
git checkout v2.1.4
composer update

/var/www以下は、ログインしたユーザであれば書き込みできるという前提で説明をします。また、ログインしたユーザはsudoコマンド可能であって、root権限が必要な処理はsudoを利用するという方針でコマンドを示します。また、ログインユーザはadminsグループにも登録してあるものとします。

前述のコマンドで、/var/www/simplesaml-idpというディレクトリができ、そこにレポジトリの内容が展開されました。このディレクトリを公開するのかというと、そうではなくて、この中のpublicを公開します。以前はwwwというディレクトリでしたが、Ver.2でpublicという名前に変えたそうです。ということで、Apache2のidp.inter-mediator.comのサイト設定ファイルは、大体以下のような記述つまり、DocumentRootがある感じです(実際には証明書の設定などもあってもっとややこしい)。/simplesamlはIdPの設定ファイルに書かれているbaseurlpathの値でもあるので、とりあえずAliasを定義しておきます。

<VirtualHost *:443>
    ServerAdmin info@inter-mediator.org
    DocumentRoot /var/www/simplesaml-idp/public
    ServerName idp.inter-mediator.com
    Alias /simplesaml "/var/www/simplesaml-idp/public"
:

さて、サーバを見てみましょう!という感じで開くと、次の通りです。当然、セットアップを何もしていないので、そのような表示が出るだけです。ちゃんと、設定ファイルがないとメッセージが出ています。

IdPが使う証明書を用意する

SAMLでは通信の暗号化のために証明書を使います。IdPで使用する証明書は、opensslコマンドを使って作成しますが、レポジトリのcertディレクトリに作るのが一番手軽です。このディレクトリに作った証明書関連のファイルは、フルパスを指定する必要がありません。例えば、以下のようなコマンドで作成できます。

cd /var/www/simplesaml-idp/cert
openssl req -newkey rsa:3072 -new -x509 -days 3652 -nodes \
    -out idp.inter-mediator.com.crt -keyout idp.inter-mediator.com.pem

コマンド例ではカレントディレクトリを明示するためにcdコマンドを随所で書くようにしますが、もちろん、コマンドの理解がある方は自分の状況に応じてコマンドを入れてください。そして、opensslコマンドの-outと-keyoutの2つのパラメータは実際に保存されるファイル名になるので、自分のドメイン等に変えるか、server.cert、privatekey.pemみたいな名前にするのが良いでしょう。

乱数生成などの後、入力を促されます。要するに大雑把な住所と組織などを入力します。以下は私が入力した例ですが、もちろん、ご自分の状況に合わせてください。Common Nameについては、FQDNを入れるのが良いと思われます。

Country Name (2 letter code) [AU]:JP
State or Province Name (full name) [Some-State]:Saitama
Locality Name (eg, city) []:Midori-ward
Organization Name (eg, company) [Internet Widgits Pty Ltd]:INTER-Mediator
Organizational Unit Name (eg, section) []:Authentication Support
Common Name (e.g. server FQDN or YOUR name) []:idp.inter-mediator.com
Email Address []:nii@msyk.net

なお、生成されたキーファイルは、ownerだけが読み書きできて、gropuやeveryoneに対する読み出し権限すらありません。Apache2のプロセスのユーザ(Ubuntuではwww-data)が読み出し権限があるようにしなければなりません。しかしながら、アクセス権は、レポジトリの内容全体に設定した方が手軽でしょうから、アクセス権の設定は最後にまとめて行います。

configディレクトリの設定を行う

それでは、設定を進めましょう。まず、レポジトリのルートにあるconfigディレクトリの中身です。このファイルには3つの設定ファイルを作りますが、そのうち、config.phpとauthsources.phpの2つのファイルを用意します。このファイルはスクラッチから作るのではなく、ファイル名に.distが付いたテンプレートのファイルがあるので、それをコピーして用意します。まず、ファイルをコピーします。

cd /var/www/simplesaml-idp/config
cp authsources.php.dist authsources.php
cp config.php.dist config.php

config.phpファイルは、以下のポイントを修正します。 そのためにvimやnanoなどのエディタで開くことになりますが、その前に、以下のコマンドを入れて、secretsaltキーの値を生成しておきます。このことはファイルのコメントにも書かれてあり、以下のコマンドで生成して、出力結果をコピーしておきます。

LC_ALL=C tr -c -d '0123456789abcdefghijklmnopqrstuvwxyz' </dev/urandom | dd bs=32 count=1 2>/dev/null;echo

そして、config.phpファイルを編集します。まず、technicalcontact*は、このサーバの管理者です。基本的には自分を指定すれば良いでしょう。secretsaltはファイルを開く前にコピーしたものを指定すればよく、文字列の中身を消してペーストします。auth.adminpasswordは、IdPのログインする管理者のパスワードです。

:
    'technicalcontact_name' => 'Administrator',
    'technicalcontact_email' => 'msyk@msyk.net',
:
    'secretsalt' => 'whr5p645s3ig7nm9wxibfckllmjfvjl6',
:
    'auth.adminpassword' => 'samltest5682',
:
    'enable.saml20-idp' => true,
    'enable.adfs-idp' => false,
:
    'module.enable' => [
        'exampleauth' => true,
        'core' => true,
        'admin' => true,
        'saml' => true
    ],

enable.saml20-idpは、文字通り、IdPの機能をアクティブにします。module.enableは、exampleauthの値をtrueにしますが、これは、設定ファイルで認証ユーザを提供する仕組みをオンにします。もちろん、簡易的にテストができるようにということです。

続いて、config/authsources.phpの修正です。まず、default-sp以下の配列において、entityIDを変更します。そして、この配列内に、privatekeyとcerificateというキーで、それぞれ秘密鍵と証明書のファイル名を指定しておきます。もちろん、ここでは、前の手順でopensslで生成したファイルを指定します。さらに、テスト用のユーザとして、example-userpassの部分のコメントを外して、その中に定義します。以下の例では、user01というユーザとuser02というユーザが定義されており、それぞれ、パスワードはuser01pass、user02passです。キーになっている’user01:user01pass’の部分でユーザ名とパスワードを表現しており、対応する配列は応答する情報を記載します。ちなみに、大学のディレクトリなどでは、eduPersonAffiliationといった属性が入ってきて、それに応じて大学生か、職員かを判断するようなロジックを求められることはよくあるようです。

:
    'default-sp' => [
        'saml:SP',

        // The entity ID of this SP.
        'entityID' => 'https://idp.inter-mediator.com/',
:
        'proxymode.passAuthnContextClassRef' => false,

        'privatekey' => 'idp.inter-mediator.com.pem',
        'certificate' => 'idp.inter-mediator.com.crt',
:
    'example-userpass' => [
        'exampleauth:UserPass',
:
        'user01:user01pass' => [
            'uid' => ['user01'],
            'eduPersonAffiliation' => ['member', 'student'],
        ],
        'user02:user02pass' => [
            'uid' => ['user02'],
            'eduPersonAffiliation' => ['member', 'employee'],
        ],
    ],

metadataディレクトリの設定を行う

続いて、レポジトリルートにあるmetadataディレクトリの設定を行います。このディレクトリも設定ファイルはないものの、拡張子が.distとなっているそれぞれのファイルのテンプレートがあるので、それをコピーして変更して利用します。3つのファイルがありますが、利用するのは2つだけです。コピーしないsaml20-idp-remote.phpファイルは、SPで利用するものです。

cd /var/www/simplesaml-idp/metadata
cp saml20-idp-hosted.php.dist saml20-idp-hosted.php
cp saml20-sp-remote.php.dist saml20-sp-remote.php

ちなみに、ファイル名がややこしいと思われるかもしれませんが、それぞれ、IdPの設定、SPの設定を行います。IdP自分自身についてはhostedの方で設定します。そして、SPの設定は自分ではないので、remoteであるということです。ファイル名にはきちんと意味があると思えば、少しは見通しよく見えるのではないでしょうか。

metadata/saml20-idp-hosted.phpについては、以下を修正します。まず、$metadata配列のキーについてはキーの値を既定値から変更して設定します。ここでは、とりあえず、IdPのドメインにしました。ちなみに、このキーを既定値のままにすると、動作がおかしかったので、これを切り替えるのが必要ではないかと思われます。そして、privatekeyとcertificateキーのファイル名を、生成したファイルのものに切り替えておきます。

$metadata['https://idp.inter-mediator.com/'] = [
    /*
     * The hostname of the server (VHOST) that will use this SAML entity.
     *
     * Can be '__DEFAULT__', to use this entry by default.
     */
    'host' => '__DEFAULT__',

    // X.509 key and certificate. Relative to the cert directory.
    'privatekey' => 'idp.inter-mediator.com.pem',
    'certificate' => 'idp.inter-mediator.com.crt',

実際にはもっといろいろ変更は必要なのでしょうけど、ここまでの設定だと、証明書やキーのファイルの整合、IdPを稼働、テストユーザの登録程度のことです。

全てのファイルの所有者とグループを揃える

必要なファイルをすべて揃えたので、simplesamlphpのファイルの所有者を、Webサーバのwww-dataに変更しておくのがいいように思います。例えば、次のようなコマンドです。

sudo chown -R www-data:admins /var/www/simplesaml-idp
sudo chmod -R g+w /var/www/simplesaml-idp

こうすれば、simplesaml-idp以下のすべてのファイルやフォルダは、所有者がWebサーバのプロセスのユーザであるwww-dataになり、グループはadminsになります。そして、所有者はrwあるいはrwxになりますが、グループも同様なアクセス権になることを期待します。通常ログインするユーザをadminsグループに入れておけば、そのユーザでのファイルの読み書き権限もあり、Webユーザの読み書き権限も確保していると言うことになります。simplesamlphpのIdPでは、ファイルの書き込み権限がWebサーバに対して必要なのかという問題はありますが、とりあえずはメンテナンスしやすい状態にしていると考えてください。

キャッシュのディレクトリを用意する

ここで、https://idp.inter-mediator.com/ つまり、Webのルートにアクセスすると次のような画面が出てきます。Ver.2.0.xではこのような画面は出てこなかったのですが、Ver.2.1.xでは出るようになったようです。

このエラーはよく読むと、意味がわかります。どうやら、既定値では、/var/cache/simplesamlphp以下のキャッシュファイルを作るようで、そのディレクトリが必要ということに加えて、アクセス権も設定が必要なようです。例えば、次のようなコマンドで対処できます。

sudo mkdir -p /var/cache/simplesamlphp
sudo chown -R www-data:admins /var/cache/simplesamlphp

キャッシュとして、かなりたくさんのファイルが作られます。

なお、simplesamlphp自体をgitを使って更新した後などは、場合によってはキャッシュをクリアしておかないと起動時にエラーになる場合もあります。エラーにならない時もあるのですが、いずれにしてもソースコードの変更によってキャッシュの整理は場合によっては自分でやらないといけない模様です。謎のエラーが出た場合には、/var/cache/simplesamlphp以下を消してみてください。

管理ツールを稼働する

ここで、https://idp.inter-mediator.com/ つまり、Webのルートにアクセスすると次のような画面が出てきます。ちゃんと動いている模様ですが、肝心の管理作業ができません。

管理作業をするには、https://idp.inter-mediator.com/admin にアクセスします。いろいろリダイレクトしますが、認証画面が出てきます。ここでは、ユーザ名はadmin、パスワードは、config.phpファイルに指定したパスワードを入力して認証します。

最初は、以下のようにTestというタブのページになります。ここから先は次の記事で説明ます。

Ubuntu 22でINTER-Mediatorを稼働する

Ubuntu Server 22.04.1 LTS上で、INTER-Mediatorのサンプルを、MySQLで動かすところまでのセットアップ方法を紹介します。サーバは普通にDVD等でインストールします。ほぼ、デフォルトでセットアップした状態を想定しているので、Minimalの方ではありません。また、サーバアプリケーションは、SSH Serverだけをセットアップ時に含めているとします。

ということで、早速、インストール後のコマンド入力です。一気にまとめて紹介します。

sudo apt -y update
sudo apt -y upgrade
sudo apt install -y apache2 php mysql-server
sudo apt install -y php-curl php-xml php-gd libicu-dev \
                    mysql-client php-pdo-mysql
sudo apt install -y nodejs
sudo apt install -y composer
sudo chmod -R g+w /var/www
sudo chown -R www-data:<user> /var/www
sudo systemctl restart apache2

cd /var/www/html
git clone https://github.com/INTER-Mediator/INTER-Mediator.git
cd INTER-Mediator/
composer update
cd dist-docs
sudo mysql -uroot < sample_schema_mysql.sql 

「php」でインストールすると、Ver.8.1がセットアップされます。モジュール類も以前よりも多く初期設定で入っているので、記載した、php-curlなど3つと、データベースのドライバを追加するだけで大丈夫です。ただ、intlモジュールが利用するlibicu-devを入れておかないといけないのは以前から変わっていないところです。php-pdo-mysqlは実は存在しておらず、php8.1-mysqlが代わりにインストールされます。php-mysqlというモジュールもあってこちらでも良さそうな気がしますが、とりあえず、PDO本体は入るけどもMySQLのPDOサポート部分は追加しないといけないというところがポイントです。よって、PostgreSQL等でも同様にPDOドライバを入れないといけないということです。

Node.jsは「念の為に」入れておきます。composerもaptでインストールできるようになっています。

Apache2は以前の通り、www-dataユーザで稼働するので、このユーザのホームである/var/wwwのアクセス権を設定しておきますが、chownでのグループはログインユーザ名にしておくのがいいかと思います。そして、Apache2を再起動します。以前よりだいぶんとシンプルになった気がします。

後半は、INTER-Mediatorのインストールです。とりあえず、Web公開ディレクトリにレポジトリの中身を展開してそれを動かすことにします。クローン後、composer updateコマンドを動かし、サンプルのデータベースをMySQLに読み込ませて準備するだけです。これで、「http://ホストIP/INTER-Mediator/samples/」で、サンプルの目次ページが出てくるはずです。

現在は既定値でサービスサーバを落としていますが、INTER-Mediator/params.phpの以下の部分を修正すると、サービスサーバが稼働します。コード部分は修正前ですので、コメントに従って変更してみてください。Sample_formフォルダのサンプルがクライアント間同期の仕組みを組み込んであります。サンプルの目次ページだと、「Any Kinds of Samples」の最初にある「Master-Detail Style Page」のリンクを利用してください。

$notUseServiceServer = true; // 値をfalseにする
/*  // この行を消してコメントでなくする
$activateClientService = false; // 値をtrueにする
$serviceServerProtocol = "ws";
$serviceServerHost = "";
$serviceServerPort = "11478";
$serviceServerKey = "";
$serviceServerCert = "";
$serviceServerCA = "";
$serviceServerConnect = "http://localhost"; // localhostを実際のホストにする
$stopSSEveryQuit = false;
$bootWithInstalledNode = false;
$preventSSAutoBoot = false;
$foreverLog = '/tmp/forever.log';
*/ // この行を消してコメントでなくする

macOSでPHPのバージョン管理

普段、最新のPHPでの検証が多いのですが、久々に、古いアプリケーションのメンテのために、8.2.0がカレントバージョンの今、7.4を使う必要が出ました。そのアプリが8.2で動いてくれればいいのですが、Warningが出るので7.4にしたいですね。当然、phpはhomebrewを使っているのですが、標準ではカレントバージョンしかサポートしていないらしく、あちこちに掲載されている「brew install php@7.4」がエラーになって動かないのです。こんな感じ。

% brew install php@7.4
Error: php@7.4 has been disabled because it is a versioned formula!

こういう場合は、上記2行目のエラーメッセージを、そのままGoogle検索窓にコピペして検索します。やはり、StackoverflowにError: php@7.3 has been disabled because it is a versioned formulaという記事が見つかりました。

ということで、標準以外のバージョンをインストールできるTapがあるということで、以下のようにコマンドを入れれば、無事にphp 7.4がカレントになりました。

brew tap shivammathur/php
brew install shivammathur/php/php@7.4

この後に、brew link …とすればいいかと思うのですが、現行バージョンのver.8.2をunlinkする前だと、–overwriteをつけろとメッセージが出てきます。以下の流れだと、–overwriteは不要かもしれませんが、エラーの時には試してみましょう。

% brew unlink php@8.2
% brew link --overwrite php@7.4
Linking /usr/local/Cellar/php@7.4/7.4.33... 25 symlinks created.

If you need to have this software first in your PATH instead consider running:
  echo 'export PATH="/usr/local/opt/php@7.4/bin:$PATH"' >> ~/.zshrc
  echo 'export PATH="/usr/local/opt/php@7.4/sbin:$PATH"' >> ~/.zshrc
% php -v                       
PHP 7.4.33 (cli) (built: Dec  8 2022 21:39:37) ( NTS )
Copyright (c) The PHP Group
Zend Engine v3.4.0, Copyright (c) Zend Technologies
    with Zend OPcache v7.4.33, Copyright (c), by Zend Technologies

そういうわけで、PHPの各バージョンは、こちらのレポジトリのようにしっかり古いものからより新しいものまでキープしてくれていることに感謝です。

[DBデザイン#47] VARCHARとTEXTどちらを使う?

ちょっと間が空いてしまいました。タイトルのテーマでサクッと書こうと思って調べ始めると、迷路に入ってしまいました。真面目に、全ての情報を書くのは多分、この話題はかなり辛いでしょう。特にMySQLの問題がありますから。ですので、いい感じのストーリにするのにちょっと時間がかかりました。マニュアルやブログを大量に読みましたが、なるべくシンプルにまとめたいと思っています。

文字列をフィールドに保存するとき、VARCHARかTEXTのいずれかの型を使うことになるでしょう。VARCHARはCHARACTER VARYINGの短縮形なのですが、VARCHARの方がお馴染みなので、こちらの表記にします。標準SQLではTEXTは定義されていないのですが、MySQL、PostgreSQLではこの2つの型のどちらかを使います。CHARという型もあるのですが、文字数を指定して定義し、足りない場合にわざわざ空白で埋めるようなことをするので結果的に固定長の文字列になりますが、現状のアプリケーションではそんなことは不要なことが多く、可変長の文字列型しかほぼ使わないでしょう。

そこで、2種類の型があるのですが、大きな違いはVARCHARは、VARCHAR(10)として、10文字(バイトではない)までの文字列を保存できるようなフィールドを用意するのに対して、TEXTは長さは指定せず、データベースの動作上の制限の長さまで入力できます。ここでいきなり例外が出ますが、PostgreSQLについては、VARCHARだけを書いて( )なしにすることで、長さの制限を無しにすることができるのですが、今回の記事では、VARCHAR(n)かTEXTかという表現で通します。

まず、2種類の型の大きな違いは、文字数の制限ができるかどうかです。文字数を制限したいかどうか? 実は制限しなくてもいいような場面が多いと思われます。逆に制限してしまった方が、意図せず制限より長い文字列を保存できなくなってしまうという問題に遭遇します。しかしながら、都道府県を保存するのにTEXTを使うのかという、かなりどうでもいいような問題に頭を悩ませてしまいます。つまり、せっかく制限が可能なのに利用しないのかというジレンマにつきまとわれてしまいますが、論理的に考えれば制限が必要になることはあまりないと思われます。

ただ、処理速度が違うだろうということは気になります。先に結論を言えば、ほぼ同じだと言えるくらいでしょう。PostgreSQLはマニュアルに、この2つの型は目立った違いがないと書いてあります。MySQLについては、1レコードのブロック内に、実際のデータを並べるのが基本動作ですが、TEXTについては原則としてそのブロック外にデータを保存するので、要するにVARCHARよりもTEXTの方が処理に時間がかかる傾向があるはずです。しかしながら、実際の運用等でもそんなに大きな差があるようには思えませんし、ベンチマークを公開しているブログ記事などを見る限りは僅かな差です。長大なデータ処理をするような場合には違いが出るかもしれませんが、一般的なUIを絡むようなアプリケーションでは多分違いはほぼ顕在化しません。ネットワーク等の他の要因の方がよほど大きく効いてくると考えられます。パフォーマンスに違いがないのなら、制約の少ないTEXTの方がいいじゃないかと思うところです。

しかしながら、MySQLに微妙な違いがあって、VARCHARはDEFAULTによる既定値の指定が可能なのに対して、TEXTはそれができません。PostgreSQLはTEXTでもDEFAULTの指定は可能です。そして、なんと、MySQL互換のMariaDBも、TEXT型でのDEFAULT指定はできます。互換を謳いながらもより高機能になっています。

この既定値については確かにデータベース定義上で行っておけば、プログラムコードは一切なく、フィールドの初期値が決められて便利です。しかしながら、都度、初期値が違うようなことも多く、結果的にプログラムで初期値を決める必要がある場合もそこそこあると思われます。長さの制限ができるという意味では、確かに不要な長いデータを保存してしまう危険性は排除できますが、本当に長さの制限をしたい場合は、おそらくUIで確認をして、長さが超えていればそもそもデータベースに命令を送ることはしないようなシステムの動作をすることができるわけです。ということで、初期値も、長さ制限も、システム内部でのケアがどっちにしても必要だとすれば、2つの型をチョイスする積極的な理由にはなりにくいでしょう。

ちなみに、SQLiteではTEXTのみです。FileMakerでも「文字型」としてフィールド定義できますが、長さの指定はできません。そんなわけで、PostgreSQLだとTEXTでいいだろうということになりそうです。MySQLではDEFAULTを設定したいかどうかによって変わるけど、長さ制限する意図がない場合にはTEXTで良いという結論になりそうです。

ただし、TEXTにも制限があるということを理解しておく必要はあります。PostgreSQLは1GBまでなので、ある意味、滅多にそこまでは行かないでしょうけど、MySQLは64KBの制限があります。しかしながら、これはバイト数なので、4バイト表現のUTF-8が基本となっているMySQLだと、最大で15,000文字くらいになり、書籍1冊分のテキストは入らないかもしれないぞというサイズです。MySQLは最大長がもっと多い、MEDIUMTEXTやLONGTEXTという型があるので、場合によってはそちらを使うことを検討する必要があります。

MySQLについては、文字列の全てがインデックスに利用されるわけではなく、Ver.5.7以降では3072バイトまでになります。また、インデックスを作成するときに、最初から何文字まで取り出すのかということを、VARCHARでもTEXTでも指定は可能です。さらに、LIKE演算子での検索では、LIKE ‘A%’のような前方一致の検索の場合しかインデックスは使用しません。長い文字列を扱う場合はインデックス対象になる範囲があることや、LIKE ‘%A%’のような〜を含むの検索をしたときにインデックスが使われないということにも注意が必要です。長い文字列に対しての検索の効率を上げるには、FULLTEXTインデックスという機能を使う必要があります。クエリーのSQLも若干違うものを使う必要がありますが、データが大きくて検索が遅い場合には検討する必要が出てくるでしょう。

MySQLのことを調べていたら、懐かしい「8KBの壁」の話が出てきました。MySQLは、8KBの領域を使って1レコードを管理する方法が取られていますが、Ver.5.6までの標準のセットアップでは、フィールドを増やせば、「思ったよりも早く」この8KBを埋め尽くしていたのでした。その時は、1つTEXTのフィールドは8KBのブロックのうち768バイトを使っていたので、10個ほどフィールドを作ればアウトだったのです。Ver.5.7からはTEXTはブロック内の20バイト程度しか使わないので、まずまずたくさんのフィールドが定義できたのでした。MySQLにはこうした「意外な頭打ち」がいろんなところにあるので、使いこなしたい方は、まずはマニュアルを熟読することが必要になるでしょう。