詳説 Data API Vol.7: Movable Type Data API のセキュリティの話
Movable Type Data API は Movable Type 6.0 から搭載されている REST API です。簡単に Movable Type に保存されている記事やアイテムなどの情報を取得したり、データの更新や新しい記事を投稿することもできます。
ただし、これらのエンドポイントを実行する場合は、適切な権限を保有しているユーザーアカウントによるユーザー認証が必要となり、ユーザー認証に失敗した場合にはリクエストを呼び出すことはできません。
また、リクエストが実行されるとき、認証されたユーザーがデータ取得などの各リクエストに対して適切な権限を有していない場合もリクエストは失敗します。
このように、セキュリティに留意して Movable Type Data API は実装されていますが、実際のセキュリティチェックはどのように働いているのでしょうか
Movable Type Data API のユーザー認証
Movable Type Data API を利用して保護されたコンテンツへアクセスするには、前述の通りユーザー認証が必要となります。ユーザー認証は、Movable Type の管理画面にサインインするアクセス方法と同様に、Movable Type に登録されているユーザーのサインイン ID と Web サービスパスワード(v1, v2 ではユーザーのパスワード)で行われます。
ユーザー認証用のエンドポイントとして、Movable Type Data API では2つのエンドポイントを用意しています
POST /authentication
スマホアプリや Web サービスなどから利用する場合は、/authentication エンドポイントを利用します。このエンドポイントは、username、password、clientId をパラメータとして受け取りユーザーを認証します。認証に成功するとアクセストークンを含む JSON を取得できます。
curl -d "username=takayama" -d "password=password" -d "clientId=test" http://host/path/to/mt/mt-data-api.cgi/v3/authentication | jq .
上記リクエストを実行すると、以下のような accessToken、sessionId、expiresIn、remember を含む JSON が取得できます。
{
"accessToken": "ZAKGe5HoDeC0d3qbuktVrMfdRlLyiwujxTI93fe8",
"expiresIn": "3600",
"sessionId": "FQIDsEl1LrYRHmeFFvEVngXbHBRt2slLMAa764ri",
"remember": false
}
- accessToken
- リクエストを呼び出すときにリクエストヘッダーに付与するアクセストークン
- sessionId
- 認証済みセッションにおいて、新しいアクセストークンを取得するための ID
- expiresIn
- アクセストークンの TTL(Time To Live: 生存期間)
- remember
- セッションを保持し続けるかを示す
/authentication エンドポイントでは、ユーザーのサインイン ID やパスワードをパラメータとして利用するため、呼び出し側でセキュリティに留意して適切に保持するか、都度入力をさせる必要があります。
GET /authorization?(redirectUrl,clientId)
ウェブサイトから利用する場合や、スマホアプリでもウェブビューを利用するときには /authorization エンドポイントを利用します。
このエンドポイントを呼び出すと、Movable Type の管理画面へサインインするのと同じようにサインイン画面が表示されます。ユーザーは、サインイン画面でユーザー認証をおこない、サインインに成功すると、エンドポイントを呼び出したときにパラメータとして渡している URL へリダイレクトされます。
アクセストークンの取得
ユーザー認証に成功し、データの取得や更新をおこなうエンドポイントを呼び出すときは、事前にアクセストークンの取得をおこないます。ただし、/authentication の呼び出しから expiresIn で指定された秒数が経過するまでは /authentication で取得した accessToken をそのまま利用することができます。
アクセストークンの取得には次のエンドポイントを利用します。
POST /token
/authentication または /autorization で取得した sessionId をリクエストヘッダーに付与して /token エンドポイントを呼び出すとセッションが有効な間は新しいアクセストークンを取得することができます。リクエストヘッダーは以下のフォーマットです。
X-MT-Authorization: MTAuth sessionId=xxxxxxxxxxxxx
curl -X POST -H "X-MT-Authorization: MTAuth sessionId=FQIDsEl1LrYRHmeFFvEVngXbHBRt2slLMAa764ri" http://host/path/to/mt/mt-data-api.cgi/v3/token | jq.
上記リクエストを実行すると、以下のように accessToken、expiresIn を含む JSON が取得できます。取得したアクセストークンには、/authentication エンドポイントで取得したアクセストークンと同様に TTL が設定されています。
{
"expiresIn": "3600",
"accessToken": "k85T6geS4inr9V38QkHyr6SzgkW63549D0LLZ4xX"
}
sessionId で指定されたセッションの有効期限が切れている場合は、401 エラーが戻ります。
認証情報を付与したリクエスト
コンテンツを更新したり、まだ公開されていないコンテンツの情報を取得する場合は、/token で取得したアクセストークンをリクエストヘッダーに付与して各種エンドポイントを呼び出します。リクエストヘッダーのフォーマットは以下のとおりです。
X-MT-Authorization MTAuth accessToken=k85T6geS4inr9V38QkHyr6SzgkW63549D0LLZ4xX
Movable Type Data API は、受け取ったアクセストークンからユーザー情報とユーザーの権限情報を特定してリクエストのセキュリティチェックをおこない、適切であると判断された場合には処理が実行されます。
Data API によるアクセスを禁止する
これまでは、Movable Type Data API のユーザー認証とリクエスト実行のためのアクセストークンの取得について説明をしてきましたが、Movable Type Data API によるデータの取得を許可したくない場合はどのようにすればよいでしょうか。
Movable Type の管理画面からウェブサイトやブログごとに Data API によるデータの取得を許可するかどうかを設定することができます。
Movable Type Data API によるアクセスを禁止されたウェブサイトやブログのコンテンツは、公開されている記事の取得などのユーザー認証を必要としないエンドポイントを呼び出されても該当するデータを返すことはありませんので、意図しないデータの流出を防ぐことができます。
Movable Type Data API に関連する環境変数
Movable Type 環境変数には前述のように Data API のアクセスを管理画面から禁止することのほかにもアクセストークンの TTL を設定する環境変数などがあります。これらの環境変数を適切に設定することでより一層セキュアに利用することができます。
Movable Type Data API を利用すれば、静的なウェブページでも動的なコンテンツを実現したり、他のサービスと連携するといったことができ、柔軟なウェブサイトでありながらセキュリティにも考慮されたサイトを構築することができるようになります。
とはいえ、セキュリティに不安がある場合や、使い方の詳細を知りたいというときは 全国各地で開催されている ユーザーグループのイベントや、東京都内であれば毎月第2第4水曜日に開催されている MTLive! に是非、足を運んでみてください。