libmysqlclient.so.18はいかにしてlibz.so.1を壊したか

  • 投稿日:
  • by
  • カテゴリ:

追記(2020年5月6日)

以下の挙動は5.7.28で確認をしていましたが、5.7.30で修正されています。

結論

同じシンボルをGLOBALで公開している複数の共有ライブラリをdlopenを使って動的にロードした場合に、解決されるシンボルがファイル間で前後することがある。

ということが原因のようです。

サンプルコード

https://github.com/usualoma/break-zlibにサンプルコードがあります。

発生した問題

以下のようなDockerfileで環境を構築したときに

「(perlでImage::Magickを使って)PNG画像のサムネイルが生成できない」という問題が発生し、条件を絞り込んでいくとどうも「DBD::mysqlをImage::Magickよりも先に読み込んだ場合に生成できなくなる」ということが分かりました。ポイントは、

  • MySQL Yum Repositoryのmysql-community-libs-compatでlibmysqlclient.so.18をインストールしている
  • libmysqlclient.so.18にリンクされた共有ライブラリを動的な環境で読み込んでいる

というころにあるようです。

この環境では、以下のようにDBD::mysqlを先に読み込んだ場合には失敗し、後に読み込んだ場合には成功します。

さらに(識者からの助言をもらいつつ)もう少し追っていくと、PNG画像の読み込み時のgzipの初期化に失敗していることが分かりました。

以下のように、zlibを直接呼び出すperlモジュールでも問題が発生します。

発生条件

色々試した結果、https://github.com/usualoma/break-zlib/tree/master/srcにあるようなコードで、

  • libmysqlclient.so.18にリンクした共有ライブラリを作成
  • libz.so.1にリンクした共有ライブラリを作成
  • それらを、libmysqlclient ->libz の順に動的にロードする

というやり方で発生させることができました。

以下のようにLD_PRELOAD使った場合には発生しなかったので「ロードの順序」だけではなく、「動的にロードすること」が条件になりそうです。

発生した理由

$ ldd /usr/lib64/mysql/libmysqlclient.so.18

の結果にlibz.so.1が含まれてもいるのですが、

$ readelf -Ws /usr/lib64/mysql/libmysqlclient.so.18.1.0

の結果にも「inflateReset」のようなlibzのシンボルがGLOBALとして含まれており、結果としてlibzの共有ライブラリとして利用できるようになっているようです。

gdbでブレークポイントを設定して見ていったところ、

  • inflateReset2は、libz.so.1のもの
  • その中で呼ばれるinflateResetは、libmysqlclient.so.18のもの

というようになっていて、それぞれに含まれるzlibのバージョンの差異によりエラーが発生しているようでした。

mysql.specを見る限り、WITH_EMBEDDED_SHARED_LIBRARYは明示的に1を指定しているようなので、libzを含むところまでは意図してやっていそうでしたが、GLOBALになっている理由はよく分かりませんでした。(mysql-community-libsからインストールされる/usr/lib64/mysql/libmysqlclient.so.20.3.15には、libzが含まれているものGLOBALではありませんでした。)

感想

mysql-community-libs-compatをインストールすると依存関係でmysql-community-libsが入り、/usr/lib64/mysql/libmysqlclient.soがlibmysqlclient.so.20を指すようになるので、MySQL Yum Repositoryとしてはlibmysqlclient.so.20を推奨っぽいので、可能な場合にはそちらにリンクしたモジュールをビルドし直した方がいいのかもしれません。

ビルドをしたくない場合、CentOSのパッケージで済まそうとすると基本的にはlibmysqlclient.so.18にリンクされていて上の状況は割と発生しそうな気がするので、その場合にはlibz.so.1を先にロードしてあげたりするなどの対応が必要かもしれません。

Squooshでアップロード時に画像を最適化する

  • 投稿日:
  • by
  • カテゴリ:

tl;dr;

こんな感じで動くMovable Typeのプラグインです。

Squooshとは

Google Chrome Labsからリリースされている、サーバーを介さずブラウザだけで画像の最適化を行うことのできるツールです。

https://squoosh.app/

Squooshは基本的には外部との連携をサポートしていないのですが、GithubにClient-side APIというプルリクエストがあったので、これを現在の最新版に適用しつつ少し改造して、外部からAPI経由で呼び出して利用できるようにしています。(IE11とEdgeでは動作させることができませんでしたが。)

プラグインについて

動作

プラグインをインストールすると、アセットとして画像をアップロードしようとした際にSquooshが開かれるようになります。右側のペインで最適化の設定を行い、「アップロード」のボタンをクリックすると、変換された結果がアップロードされます。

「画像をアップロードする際にSquooshを適用する」のチェックを外してアップロードすると、Squooshを適用せずにそのままアップロードすることができます。

mt-plugin-squoosh-each-upload.png

またSquooshの適用する場合、アップロード時にファイル名を変更することができます。「IMG_1234.jpg」のような名前のファイルを、公開時には異なるファイル名にしたいことがあると思いますが、そういったケースでも事前にローカル環境でファイル名を変更しておくことなく、アップロード時にファイル名を指定することができます。

mt-plugin-Squoosh-rename.png

設定

システムのプラグイン設定で、Squooshをデフォルトで有効にするかどうかを指定することができます。

mt-plugin-Squoosh-system-config.png

またユーザー設定で、自分の好みに合わせてデフォルトで有効にするかどうかを指定することができます。

mt-plugin-Squoosh-per-user.png

動作するMTのバージョン

  • Movable Type 7

動作するブラウザ

  • Google Chrome
  • Firefox
  • Safari

リサイズ等を自動で行いたい場合

「指定した大きさへ自動でリサイズ」のようなことはこのプラグインではできないので、その場合にはImageUploadUtilityのようなプラグインを利用するとよいと思います。(ImageUploadUtility Proならウォーターマーク自動合成などの処理もできるようです。)

最適化を自動で行いたい場合

自動での最適化はこのプラグインではできないので、その場合にはLightFileのような画像軽量化サービスを利用するとよいと思います。

この記事について

この記事は Movable Type Advent Calendar 2019 の25日目の記事です。今年も無事完走できたようでほっとしました。参加された方、また楽しみに待っていただいた方、皆様お疲れさまでした。Advent Calendarを作成していただいた西山さん、ありがとうございました。それでは良いお年を!

tl;dr;

MTAppjQueryを使っている場合にはuser.jsに以下のような記述を追加すると、A要素の中にDIV要素をいれてもリッチテキストエディタに変更されてしまうというトラブルを回避できます。

どんな問題か

HTML5ではA要素に入れられる内容が結構幅広くなっているので、DIV要素も入れらるようになっているのですが、Movable Type(r.4603以下)のリッチテキストではソースモードで入れたとしても消されてしまったりという問題があります。

具体的には、ソースモードなどから以下のようなHTMLを入力した時に、WYSIWYGモードに戻して保存するとA要素が消えるなどの症状が発生します。

<a href="#"><div>contents</div></a>

ポイントは2点あって、それらが合わさって意図しない書き換えが発生しています。

  • A要素の中にDIV要素を入れることが正しくないと認識されてしまう。
  • A要素がトップレベルにあると、最上位の要素としてP要素が補完されてしまう。

これらを回避するのが上の設定です。

「forced_root_block: false」をすると最上位のP要素の補完がなくなるので、それが好ましくない場合には設定の方を以下のようにした上で、

記事を書くときに、以下のように「A要素を最上位にせずにDIV要素で囲む」などの運用でカバーすることもできると思います。

<div><a href="#"><div>contents</div></a></div>

MTMLとJavaScriptで、Movable TypeをHeadless CMSとして使う

  • 投稿日:
  • by
  • カテゴリ:

Headless CMSとMovable TypeとData API

Headless CMSを簡単に説明すると、「コンテンツをグラフィカルな表現で閲覧するための機能をもたない、データを管理するためのバックエンド側の機能のみを提供するCMS。一般的にコンテンツの公開はAPIを通じて行われ、CMSとは切り離された方法でグラフィカルな表現に変換される。」といったところでしょうか。(英語版Wikipediaにはページはあったのですが、やや偏っている印象もあったので引用はしませんでした。)デバイスの多様化に伴い、数年前からよく聞くようになってきたCMSのトレンドの一つだと思います。

MTはテンプレートを書いてファイルとして書き出すのが基本なので、これを「グラフィカルな表現に変換する機能」すると、その面から見たときはHeadless CMSではないと考えるのが妥当だと思います。

しかし一方で、MTではData APIというRESTfulなAPIを使ってコンテンツを取り出すこともできるので、これを使えばMTをHeadless CMSと考える(Headless CMSとして使う)こともできると思います。

この記事では、

  • Data APIを利用して
  • しかしJavaScriptなどのプログラムを意識することなく
  • 馴染みのあるMTタグを使って
  • MTをHeadless CMSとして使う

ということを実現できるツールを紹介します。

MT Data API React

MT Data API Reactは、Data APIで取得したデータをMTタグで書いたテンプレートでHTMLに変換して表示することのできるツールです。

以下のURLで試すことができます。「ブログのエンドポイント」に試したいブログのData APIのエンドポイントを入れれば、そのデータでブラウザ上で対話的に動作を確認することができます。

https://usualoma.github.io/mt-data-api-react/docs/playground.ja.html

「開発環境」タブの手順で「SFTPでテンプレートを更新して確認」や、「開発環境」のタブの手順で「本番環境では軽量化のために書き出したテンプレートを利用する」といったこともできます。

特徴

MTタグを書くだけで簡単に設置できる

これが最大の特徴ですが、JavaScriptを1行も書くことなくMTタグを書くだけで設置できます。

「JavaScriptを使ってAPIで取得したデータを表示する」というのもシンプルな作業ではあるのですが、実際にやるとなると「Data APIの仕様を理解する」という学習は必要になります。またJavaScriptを使うので安易に実装するとXSSなどの脆弱性に繋がる可能性があります。

MovableTypeにある程度なれている場合には、MTタグを使ってHTMLを構築するのは容易なはずなので、新しい学習のコストや脆弱性のリスクなしに、簡単に設置することができます。

ただこの部分には課題もあり、現状では使えるタグは少ないので、「サイト全体を構築する」ということはまだ難しい状態です。

JSはそれほど重くない

読み込みに必要なJSは、圧縮した状態で90KBほどです(2019年12月現在)。軽いとはいえないサイズですが、利便性とのトレードオフで考えれば許容できるサイトも多いのではないかと思います。

用途

外部のサイトへの埋め込み

メインのサイトの表示としてではなく、外部のサイトへの埋め込みの用途として利用できると思います。

  • 「新製品の特設サイト」と「コーポレートサイト」を別のMT、別の組織で管理している
  • 「コーポレートサイト」でも「新製品」のニュースを表示したいが、デザインは「コーポレートサイト」の方で管理したい

というケースで、従来であれば「JSON形式でファイル書き出してからAJAXで読み込んで表示」という手順になったと思いますが、これを(内容を示し合わせた)JSONファイルを書き出したりすることなく、表示する側で柔軟に管理できるようになります。

Rubyの関数オブジェクト

  • 投稿日:
  • by
  • カテゴリ:

tl;dr;

基本的には以下のページで説明されているとおりだと思います。

この記事は、これらを少し長めのコードで試してみたものです。

関数オブジェクトを取得

Object#methodで取得できるとのことで、まずは試してみました。

以下のことが分かりました。

  • トップレベルでのメソッド定義はmodule Kernelにプライベートメソッドとして追加される
    • トップレベルのselfであるmainで呼べるようになる
  • method(:hello) (つまり self.method(:hello) で)トップレベルの hello をオブジェクトとして取得できる
  • 定義したクラスのメソッドも instance.method(:hello) で取得できる

レシーバの確認

Object#methodから返ってくるのはclass Methodのオブジェクトで、「メソッドの実体(名前でなく)とレシーバの組を封入します」とのことなので、どのような意味か確認しました。

Object#methodを呼んだ際のレシーバが、暗黙のレシーバであるselfとして封入されていそうです。

Procはどうなっているか?

暗黙のレシーバの確認をしていて、そういえばProcだどどうなんだろうと思って調べてみました。

Procは「ブロックをコンテキスト(ローカル変数のスコープやスタックフ レーム)とともにオブジェクト化した手続きオブジェクトです」とのことなので、selfへの参照も含まれるということだと思います。

class UnboundMethodの存在

ここまで忘れていましたが、Module#instance_methodを使うと、レシーバをもたないオブジェクトを取得することができるようです。

Module#instance_method に「バインドできるのは、 生成元のクラスかそのサブクラスのインスタンスのみです。」とあるとおり、確かにサブクラスでもないObjectをbindしようとしたらTypeErrorになりました。

まとめ

  • Object#methodで関数オブジェクトを取得できる
  • 関数オブジェクト(MethodやProc)はレシーバの情報ももっていて、オブジェクトをcallした場合にはそれが暗黙のレシーバとして使われる
    • レシーバをもたないclass UnboundMethodもあるが、UnboundMethod#bindしないと呼べない

ということのようです。

これは何か?

iOSの「ショートカットアプリ」用のショートカットをサーバー側で生成して、iPhoneからはQRコードを読むだけでインストールできるようにする、Movable Typeのプラグインです。

ShortcutsApp

このプラグインを使って生成したショートカットでは「Data APIのURL」のような設定が最初から埋め込まれているので、iPhone側では何も設定することなく利用することができます。(「Webサービスのパスワード」も埋め込むことができますが、暗号化はされません。その辺りの問題については以前の「iOS12のショートカットアプリとMovable TypeのData API」のサンプルの記事の「サンプルを利用する場合の注意事項」参照してください)

使い方

プラグインのZIPファイルをダウンロードして、Movable Typeへインストールすると利用できるようになります。設定は特に必要ありません。

インストールすると左側のメニューに「ツール > ショートカット.app」が追加され、メニューをクリックすると利用できるショートカットの一覧が表示されます。一覧からは、「インストールボタンのクリック -> iOS端末でQRコードを読み込み -> 表示された画面からインストール」の流れでiOS端末にショートカットをインストールすることができます。

管理者ユーザーでアクセスしている場合には、一覧のインストールボタンの左側にユーザーアカウントの選択肢が表示されます。「パスワードを埋め込む」を選択した場合には、ここで選択したユーザーのWebサービスパスワードが埋め込まれたショートカットを用意できます。これを使うと「管理者ユーザーが代理でMT上で操作を行い、ショートカットの利用者にはメールでインストール用のURLを送る」というような運用をすることができます。

同梱されているショートカット

以下の2つのショートカットが同梱されています。

写真を投稿

「写真」アプリのシェアボタンから、ショートカットを選択するとそのまま記事を投稿できます。以前の記事の「iOS12のショートカットアプリとMovable TypeのData API」のサンプルで紹介したショートカットと同じものです。

「パスワードを埋め込む」を選択していない場合には、投稿時にWebサービスのパスワードの入力が必要になります。

再構築

すべてのテンプレートを再構築します。

システムコンテキストからインストールした場合にはMovable Type 内のすべてのサイトが、サイトのコンテキストでインストールした場合にはそのサイトが、それぞれ再構築されます。

Siriに再構築をお願いすることもできます。

ショートカットの追加

ショートカットは、「テーマ」のように後から追加することもできるようになっています。

ショートカットの書き出しファイルの仕様は以前の記事でも触れたのですが、アプリから書き出されるバイナリファイルをXML形式に変換して編集することが可能です。また、以前の記事の時点からの新しい発見もあって、「ショートカットアプリには、XML形式を再びバイナリに戻して読み込ませる必要がある」かと思っていたところ必ずしもそうではなく「shortcuts://import-shortcut というURLを使った場合には、XML形式のまま読み込ませることができる」ということが分かりました。このプラグインではこの方法を利用して、ショートカットをMTMLを使ったテンプレートで管理しています。バイナリ形式に戻す必要がないため(XMLファイルさえ生成できればよいので)、インストール先のサーバー環境を選ばずに動作するようになっています。

具体的なカスタマイズの手順

手順は以下の通りです。

  1. iOSのショートカットアプリでショートカットを作成する
  2. ファイルとして書き出す
  3. XML形式に変換する
  4. ショートカットの定義(プラグイン独自の shortcut.yaml )を書く
  5. プラグイン内のshortcutsディレクトリの下に入れる

1が非常につらい作業(ショートカットアプリ内で、GUIでかつ限りられた機能だけでのプログラミング)ではありますが、他は特に難しいことはないと思います。基本的にはテーマを追加するのと同じような手順です。

XML形式への変換

Macであれば以下のコマンドが利用できます。

plutil -convert xml1 -o MT用テンプレート.tmpl 書き出したファイル.shortcut

またはDockerを利用できる環境であれば、以下のコマンドが利用できます。

docker run -it --rm -v $PWD:/files usualoma/libplist plistutil -i /files/書き出したファイル.shortcut -o /files/MT用テンプレート.xml.shortcut

shortcut.yamlを書く

ショートカットの定義をshortcut.yamlに書きます。テーマでのtheme.yamlのようなもので、主なキーの意味は以下の通りです。

  • id : ショートカットのID
  • label : MTの管理画面上での名前
  • version : バージョン
  • name : インストール先のショートカットアプリでの名前
  • description : ショートカットの説明
  • install_instruction : インストールの手順などの説明文
  • view : 利用可能なコンテキスト(system、website、blog)
  • template : ショートカットのテンプレートのファイル
  • expires_in : インストール用URLの有効期限の秒数

同梱されているショートカットを雛形にすると簡単かもしれません。

トラブルシューティング

写真の投稿ができない

iOSの問題だと思うのですが、時々ショートカットが正常にインストールできないことがあり、「写真の情報を取得できない」という問題が発生することがあります。この問題は「インストール前に写真アプリを開いておく」ということで発生確率を下げることができそうなのですが、それでも発生することが稀にあります。

発生した場合には、インストールしたショートカットを一度削除して、インストールし直すという手順で修正されると思います。

まとめ

「写真アプリからのシェア操作で投稿できる」というのはなかなか新鮮な体験だと思うので、ぜひ試してもらえればと思います。

またこのプラグインの例ではでは「写真のアップロードから、記事の作成と公開」まで行っていますが、もっとシンプルに「写真をアップローロドするだけ」というようなショートカットも実際の運用では便利だったりすると思うので、ショートカットアプリとData APIを連携は考え方しだいで、いろいろと面白いことができそうな気がします。

この記事について

この記事は Movable Type Advent Calendar 2018 の10日目の記事です。

Happy Holidays!

発生する条件

php.iniで以下のように設定されている時に、multipart/form-dataでUTF-8の内容をPOSTすると文字化けすることがある。(application/x-www-form-urlencodedでは文字化けしない)

mbstring.encoding_translation = On
mbstring.http_input = auto
mbstring.internal_encoding = UTF-8

どんな流れで発生しているか?

PHPではPOST時のハンドラをMIMEタイプ毎に登録する仕組みになっているようで、mbstringでは以下の場所でapplication/x-www-form-urlencodedとmultipart/form-dataで別々のハンドラが登録されている。

https://github.com/php/php-src/blob/master/ext/mbstring/mbstring.c#L680-L681

application/x-www-form-urlencodedの場合はmbstring内でリクエストのボディ全体から文字コードを判定するため、期待した通りUTF-8として扱われる

multipart/form-dataの場合は以下の場所で文字コードの判別が行われるが、

https://github.com/php/php-src/blob/master/main/rfc1867.c#L427-L429

判別対象のデータが例えば以下のようなヘッダー行なので、

Content-Disposition: form-data; name="name"

「mbstring.http_input = auto」 => 「ASCII,UTF-8」だとASCIIだと判定されてしまい。その下に続く内容もASCIIとして「ASCII -> UTF-8」で変換が行われてしまう。

回避方法

以下のような方法がある。

  • 「mbstring.http_input = UTF-8」にする
  • フォーム要素に「multipart/form-data」をつけない
  • 全ての項目のname属性にマルチバイトの文字を入れる

以下のようなフォームであれば文字化けしない。

<form enctype="multipart/form-data" method="POST">
<input name="📛" value="天野" />
</form>

この記事について

iOS12で利用できるようになったショートカットアプリは、自分の好みの「手順」をSiriから呼び出せるようにしたりホーム画面にショートカットを作ったりできるというものですが、その中でどうやら「手順」としてウェブAPIへのリクエストをなかなか自由にできるらしいという話を聞いたので、それならばということで、Movable TypeのData APIとの連携を試してみました。

この記事では、実際の運用でありえそうなパターンとして以下の3つのサンプルを紹介します。

  • 写真を選択して記事を作成
    • 写真は複数選択が可能で、記事には写真を撮影した際の位置情報が付与されます。
  • Evernoteから記事を作成
  • コンテンツタイプとしてURLを収集

それぞれのパターンについて、項目の下の方にエクスポートした「.shortcut」へのリンクを置きました。iOS12でショートカットアプリをインストールしてあれば、実際にショートカットを試してみることもできます。(動画では実行時にパスワードが表示されてしまっていますが、「.shortcut」からインストールされるバージョンでは実行しただけでは表示されないように修正されています。)

対象になるMTのバージョン

コンテンツタイプを利用するサンプルではMT7が必要です。それ以外のサンプルはMT6でも動作します。

写真を選択して記事を作成

ショートカットアプリを使うと「共有シート」に項目を追加して、選択した写真を「ショートカット」に渡すことができるようになります。

このサンプルではそれを使って、以下の操作で記事を作成できるようにしてみました。

  1. 写真を選択(複数可)
  2. シェアボタンから、登録したショートカットを選択
  3. タイトルと本文を指定

写真はアセットとしてアップロードされ、記事の本文に挿入されます。(カスタムフィールド版もあります)写真に位置情報が含まれている場合には、緯度と経度も投稿情報に含まれます。

MTへ画像を投稿.shortcut

カスタムフィールド版

カスタムフィールド版では、「記事」に対して以下のようなベースネームを持つフィールドが設定されていることを想定しています。

  • image
  • latitude
  • longitude

1枚目の画像がimageのフィールドに入り、2枚目以降の画像は本文に挿入されます。

MTへ画像を投稿(カスタムフィールド版).shortcut

Evernoteから記事を作成

メモアプリや編集アプリからデータを受け取り、MTで記事を作成するパターンです。ここではEvernoteと連携させています。

Evernoteでは普通に書くとh2、h3などの細かい指定はできないため、以下のような形で置き換えるようにしています。

  • 太字 -> h3
  • リスト -> そのまま
  • その他 -> divなどは削除し、極力シンプルなHTMLになるようにする

変換結果がやや不安定なので、このサンプルは現実的に使い物になるかどうかはやや微妙です。Markdownの編集アプリからそのままMarkdownとして投稿などの方が現実的かもしれません。

EvernoteからMTへ投稿.shortcut

コンテンツタイプとしてURLを収集

スマートフォンからアクションすると考えると、「記事」よりも細かい(「ソーシャルブックマークに追加」程度の)粒度でなにかできるとよい場合もあると思います。このサンプルでは、以下のようなフローで記事作成を行うための「URLの収集」をショートカットでできるようにしてみました。

  • 記事にするURLをスマートフォンで収集しておく
  • 後で収集したURLを組み合わせて「まとめページ」をつくる

こういった場合には、MT7のコンテンツタイプが使えそうです。

  • URL
  • タイトル
  • og:image
  • 埋め込みHTML

といったフィールドをもつコンテンツタイプを作り、ここにデータを貯めていきます。「タイトル」「og:image」はショートカットの中で自動で取得します。「埋め込みHTML」はURLがTwitterの場合にのみ、oembedのAPIを使って自動で取得します。(少し拡張すれば、YouTubeなどoembedのAPIを提供している他のサービスでも取得できるようになります)

URLをMTへ保存.shortcut

管理画面の方は以下のような雰囲気です。

ref-page-type.png
「参照ページ」コンテンツタイプ
a-ref-page.png
参照ページの編集
curation-page-type.png
「まとめページ」コンテンツタイプ
a-curation-page.png
まとめページの編集

サンプルの紹介は以上になります。

サンプルを利用する場合の注意事項

これらのショートカットアプリではWebアプリのパスワードを利用するのですが、「テキストデータ」としてしか保存する方法が見つからなかったので、「ショートカット」を開くと確認できる状態で保存されます。一応、通常の使用では表示されないように工夫はしているのですが、アプリから開くと容易に表示可能です。特に強い権限を持つユーザーで利用する場合には注意が必要です。(「iCloudキーチェーン」が使えるとよさそうなのですが、それはまだできないようで。)

「ショートカット」の可能性

ショートカットアプリで作成した「ショートカット」は共有のために書き出すことができるのですが、書き出されるファイルは(バイナリの)plist形式なので、少し手を加えることでテキストエディタで編集することもできます。Macであれば以下のようなコマンドを実行することで編集が可能です。(Linuxにも同様の結果を得ることができるコマンドがあります)

テキストとして編集できることにより、例えば以下のようなことができるようになります。

  • エンドポイントの設定の埋め込み
  • ユーザーIDやパスワードの埋め込み
  • メッセージの多言語化

これらを利用することで、例えばリテラシーの高くないユーザーに対しても「(編集済みの)ショートカットを受け取ってインストールするだけで、エンドポイントやパスワードを設定しなくても利用できる」というようにすることができそうです。

まとめ

これはなかなか面白いものだと思います。上のサンプルよりもっとシンプルなものでも、例えば「アセットの一括アップロード」だけでも十分に役立ちそうなので、MTを使っているならば(特別にマッチするような運用ではなくても)普通に便利に使えるような気がしています。 パスワードをそのまま埋め込まざるを得ないなど、現状としては課題もありますが、それらは今後のアップデートを(あまり期待せずに)待ちたいと思います。

MFA - MTで多要素認証を有効にするプラグイン

  • 投稿日:
  • by
  • カテゴリ:

Movable Typeで、サインイン時に多要素認証を利用できるようにするプラグインを公開しました。

現時点では「Eメールによる確認コードの送信」と「Google Authenticator(TOTPが利用できるデバイスやアプリ)による確認コードの生成」に対応しています。(どちらか一方のみを、システムで有効化できます)

いずれのプラグインも、Movable Type 6 でも Movable Type 7 でも利用できます。(どちらかというと Movable Type 7 に最適化されています)

Eメールによる確認コードの送信

デモ

使い方

以下の2つのプラグインをインストールします。

インストールすると全てのユーザーで、サインイン時にEメール経由で送信される確認コードの入力が必要になります。

Google Authenticatorによる確認コードの生成

デモ

インストールに必要な要件

CPANモジュールのDigest::HMAC_SHA1を必要としています。マネージドなレンタルサーバーではインストール済みであることが多いと思います。自分で環境を構築している場合には明示的にインストールする必要があるかもしれません。

また、同じくCPANモジュールのMath::Random::MTは、必須ではないものの推奨されています。このモジュールがインストールされていると暗号的により好ましい設定が生成されます。(ただ、多要素認証はパスワード認証を補強するものであるので、「インストールされていなくてやや好ましくない設定が生成される」状態ではあっても、充分に有用なものであると言えると思います)

使い方

以下の2つのプラグインをインストールします。

インストールすると各ユーザーが、ログイン後に「システム > 多要素認証」のメニュー内の「Google Authenticator」で有効と無効を切り替えられるようになります。Google Authenticatorだけでなく、 AuthyなどTOTPに対応している多要素認証のコードを生成するアプリケーションであれば利用できると思います。有効化されているユーザーでは、サインイン時に確認コードの入力が必要になります。

万が一、デバイスを紛失するなどでコードが生成できなくなった場合には、管理者としてサインインすると「システム > ユーザー」で多要素認証のリセットを行うことができます。(管理者がサインインできなくなった場合にはまずは落ち着いて、その後プラグインをアンインストールしてサインインして、サインイン状態のまま再度インストールするとサインイン状態が維持されるので、そこでリセットの操作を行うことができます)

TODO

現時点では、これらのプラグインでは最低限の機能しか提供されていませんが、今後としては以下のような展開があってもいいかもしれません。

  • リカバリーコードを利用できるようにする
    • デバイスが手元になかったり紛失したりしてしまった場合に利用できる、リカバリーコードを生成できるようになるとよさそうです
  • 有効にする認証のタイプを選択できるようにする
    • 現在は、システム全体でEメールかGoogle Authenticatorのどちらか一方しか利用できないので、ユーザー自身で複数のタイプから選択できるようになるとよさそうです
  • 多要素認証のポリシーをシステム全体で設定できるようにする
    • 「多要素認証を、全てのユーザーで必須にする」などのポリシーを定められるようになるとよさそうです

この記事について

この記事は Movable Type Advent Calendar 2017 の21日目の記事です。

MySQLの「Incorrect string value: '🍣'」問題

  • 投稿日:
  • by
  • カテゴリ:
CREATE TABLE `注文` (
  `内容` TINYTEXT CHARACTER SET utf8mb4
);

なテーブルに、🍣だけをたくさん挿入しようとすると「Incorrect string value: '🍣'」になる。

> INSERT INTO `注文` (`内容`) VALUES (REPEAT('🍣', 64));
ERROR 1366 (HY000): Incorrect string value: '\xF0\x9F\x8D\xA3' for column '内容' at row 1

🍣 と 🍺の場合には「Data too long」になる。

> INSERT INTO `注文` (`内容`) VALUES (REPEAT('🍣 と 🍺', 64));
ERROR 1406 (22001): Data too long for column '内容' at row 1

TEXT系のカラムの場合にはカラムのサイズで切ったバイト列に対して正しい文字列かどうかを判定していて、そのためマルチバイトのエンコーディングで文字の途中で切られた場合には(実際には「Data too long」という理由で切られたのに)「Incorrect string value」となっていたということのようでした。

Bug #87100として報告してStatusはVerifiedになったのですが、その後動きがないように見えるので、今後どうなるかはよくわかっていません。