Movable Type の Data APIを利用して「秘密のブログ」を作る

前回の記事では、Movable Type のData APIについて、概要と簡単な使い方をご紹介しました。

今回は、Data APIの[認証]機能を使って、より具体的な構築を行っていきましょう。

秘密のブログを実装する

ニュースサイトや会員向けのサービスで

  • ニュースや情報の前半部分が公開されている
  • 続きを読むためには、IDとパスワードでサインインが必要
  • サインインが成功すると続きが表示され、ぜんぶの文章が読める

という仕組みのページがあります。このような仕組みを Movable Type のData API を利用して構築し、認証が成功しないと記事の全文が読めない 「秘密のブログ」を作ってみましょう。(注)

「秘密のブログ」の仕様は以下とします。

  • Movable Type の[本文]と[続き]に文章を入力する
  • 公開した記事のページ上では、最初は[本文]しか表示されていない
  • 続きを読むためには[サインイン]を行う必要がある
  • [サインイン]で認証が成功すると、[続き]の文章が読めるようになる
  • [サインアウト]を行うと、再び記事の[続き]が非表示に変わる

今回は、Movable Type の標準テーマである [Rainier] の記事テンプレートを利用して実装します。

(注:シナリオの流れをご理解いただくために「秘密」と書きましたが、公開済みの記事はData APIからデータを取得できるため、厳密に言うと「完全に秘密」な状態ではありません。実装の際はご注意ください。)

「秘密のブログ」の流れ

まず、Movable Type の本文を入力します。

image03

[続き]を入力して、公開します。

image05

公開された記事。[本文]に入力された部分しか表示されていません。

image09

[サインイン]ボタンを押すと、認証画面が表示されます。

image06

認証が通ると、[続き]に書かれた文章が読めます。

image08

実装コードの解説

それでは、実際のコードを見て行きましょう。

まず、HTMLヘッダーに、Data APIのJavaScript用SDKを読み込みます。以下のコードを、<head>~</head>内の任意の場所に記述します。

<script type="text/javascript" src="<mt:StaticWebPath>data-api/v2/js/mt-data-api.min.js">

次に、Rainierのアーカイブテンプレートから [記事] テンプレートを修正します。

下記は、Movable Type の[Rainier]の元のテンプレートです。MTタグを利用して、記事の[本文]を<$mt:EntryBody$>、[続き]を<$mt:EntryMore$>で表示しています。

                <div class="entry-content asset-content" itemprop="articleBody">
                  <$mt:EntryBody$>
                  <$mt:EntryMore$>
                </div>

上記のコードから、<$mt:EntryMore$> の部分を変更します。太字の部分が変更した部分です。

                <div class="entry-content asset-content" itemprop="articleBody">
                  <$mt:EntryBody$>
                  
<script type="text/javascript">

var api = new MT.DataAPI({
    baseUrl: '<MTCGIPath>mt-data-api.cgi',
    clientId: 'secret',
    sessionPath: '/',
});

var html = '';
var siteId = <$MTBlogID$>;
var entryId = <$MTEntryID$>;

     function display() {

        if (! api.getTokenData()) {
            
            html += "<p>記事を読むためにはサインインしてください。</p>";
        html += "<p><input type=\"button\" onClick=\"SignIn()\" value=\"サインイン\"></p>";

            document.getElementById("more");
            more.innerHTML = html;

        }
        else {

            api.getEntry(siteId, entryId, {fields: "more"}, function(response) {
               if (response.error) {

            html += "<p>通信エラーが発生しました。もう一度ページを再読み込みしてください。</p>";

            document.getElementById("more");
            more.innerHTML = html;
               
                 return;
               }

                 html += response.more;
                 html += "<p><input type=\"button\" onClick=\"SignOut()\" value=\"サインアウト\"></p>";

                 document.getElementById("more");
                 more.innerHTML = html;

             });

        }
    }


    function SignIn() {

                 location.href = api.getAuthorizationUrl(location.href);

    }

    function SignOut() {

        api.revokeAuthentication(function(response) {
          if (response.error) {
            alert ('ログアウトに失敗しました。');
            return;
          }
          else {

          location.reload();
          
          }

        });
    }
window.onload = display;
</script>

<div id="more"></div>

                </div>

コードの中身を詳しく解説していきましょう。

最初に、前回同様、Data APIを利用してオブジェクトを生成します。Data APIを利用するためのCGIスクリプトのURLと、clientIdを指定します。clientIdは任意の文字列をつけます。ここでは、「secret」としてみました。

var api = new MT.DataAPI({
    baseUrl: '<MTCGIPath>mt-data-api.cgi',
    clientId: 'secret',
    sessionPath: '/',
});

次に、JavaScript内で利用する変数を定義します。変数htmlは、画面上に表示するメッセージデータを格納するために使います。変数siteId、entryIdは、表示している記事のブログID、記事IDを格納しています。

var html = '';
var siteId = <$MTBlogID$>;
var entryId = <$MTEntryID$>;

次に関数 display を定義します。ここでは

  • JavaScript SDKのエンドポイント[getTokenData]を利用してトークンのデータを取得
  • トークンが空=認証が済んでいない場合、サインイン用のボタンを表示して、<div id="more"></div>の行に表示する。ボタンを押すと、関数 [SignIn] を実行する。
  • 認証が済んでいる場合、JavaScript SDKのエンドポイント[getEntry]を利用して、ブログID、記事IDを指定して[続き]のデータを取得する。サインアウト用のボタンと組み合わせて、<div id="more"></div>の行に表示する
  • サインアウトのボタンを押すと、関数 [SignOut] を実行する

というロジックを実行しています。

function display() {

        if (! api.getTokenData()) {
            
            html += "<p>記事を読むためにはサインインしてください。</p>";
        html += "<p><input type=\"button\" onClick=\"SignIn()\" value=\"サインイン\"></p>";

            document.getElementById("more");
            more.innerHTML = html;

        }
        else {

            api.getEntry(siteId, entryId, {fields: "more"}, function(response) {
               if (response.error) {

            html += "<p>通信エラーが発生しました。もう一度ページを再読み込みしてください。</p>";

            document.getElementById("more");
            more.innerHTML = html;
               
                 return;
               }

                 html += response.more;
                 html += "<p><input type=\"button\" onClick=\"SignOut()\" value=\"サインアウト\"></p>";

                 document.getElementById("more");
                 more.innerHTML = html;

             });

        }
    }

次に関数 SignIn を定義します。ここでは

  • エンドポイント[getAuthorizationUrl] を利用して、Movable Type のサインイン画面のURLを取得し、移動する

を実行します。

    function SignIn() {

                 location.href = api.getAuthorizationUrl(location.href);

    }

次に、関数SignOutを定義します。ここでは

  • エンドポイント[revokeAuthentication] を使って、セッションを破棄する
  • 「location.reload」 で画面を再読み込みする

を実行します。

 function SignOut() {

        api.revokeAuthentication(function(response) {
          if (response.error) {
            alert ('ログアウトに失敗しました。');
            return;
          }
          else {

          location.reload();
          
          }

        });
    }

最後に、

  • 記事ページの読み込みが完了後、[window.onload] ハンドラで関数displayを実行する
  • メッセージや記事データの表示に使うための<div id="more"></div> を設定する

を行っています。サインイン用のボタンや、サインイン終了後の[続き] の文章は、[getElementById] でid=moreの

要素に表示されます。

 

window.onload = display;
</script>

<div id="more"></div>

いかがでしたか?今回は、Movable Type のData APIを利用して、認証と記事データの表示を行いました。

Data APIを利用すると、Movable Type の認証システムを使うことができるため、セキュアな認証を利用することができます。

みなさんも、Data APIの[認証]の機能を利用したサイト構築に挑戦してみてください!