WordPress 問い合わせページを共用SSLでSSL化する
サイト全体の常時SSL化を推進することになり、リニューアルサイトの提案時には必ずSSL化予算を確保していただけるよう呼びかけています。
しかし、零細企業、小企業ではSSL化の必要性をご理解いただけない事例が、ごく稀に存在します。広報/Web担当者のスキルや品質管理、熱意で企業の情報発信が大きく左右されること、情報発信によって新たな光明を獲得できること、企業サイトの制作には様々な可能性があることを日々実感しています。
個人企業や予算が少なすぎるサイトで共用サーバをレンタルする場合は、SNI SSLを利用できるサーバをおすすめします。独自ドメインによるSSL運用でCMSを利用する際にスムーズにSSL対応することができます。
今回はかなりイレギュラーなケース「共用SSLで問い合わせページだけSSLで表示する。」に対応する方法です。さらにイレギュラーなのが、共用SSLにサブディレクトリが付与されるレンタルサーバに対応します。
共用SSLには「https://sahred.example-server.com」というドメインのみのサーバと、「https://sahred.example-server.com/~shared-ssl-directory/」というサブディレクトリが付与されるサーバがあります。今回は後者に対応する方法の一つです。
共用SSLとWordpress
WordPressなど多くのCMSは一部の共用SSL(shared ssl)サーバヘの対応が不完全です。理由はサーバの環境として共用SSLのサブディレクトリがルート・ディレクトリに含まれていないためです。URLの表示上は「~shared-ssl-directory」というサブディレクトリが付与されたものがルートですが、PHPで取得されるサーバのルートはドメインまでなので、WordpressやHTMLはサブディレクトリで動作しています。httpサイトとシステムが認識するディレクトリ構造が変わってしまいますので画像やファイルのパスが正しく取得できませんでした。
対応手順
おおまかに、以下の手順で共用SSLページを作成します。
1 問い合わせページだけ、外部のPHPファイルからWordpressを動作させる。
2 wp-configでサイトのURLなどを設定する
3 共用SSLの時だけWordpressのURL取得関数にサブディレクトリを付加する
4 htaccessでSSL on/offのリダイレクト
お問い合わせページを作成する
今回はChronoforms プラグインを利用して問い合わせフォームを作成しました。
固定ページにフォーム用のショートコードを記述して「お問い合わせ」ページを作成します。
※基本的にはほとんどの問い合わせフォーム作成プラグイン、WordpressやJoomla!などの汎用CMSはドメイン名が変わってしまう「共用SSL」に対応していません。
Chronoformsは遷移URLを相対パスで管理できるため利用してみました。(http://example.com/などスキームとドメイン名が強制的に出力されるプラグインは利用できませんでした。
この固定ページは直接表示できないよう、リダイレクト用のプラグインなどで共用SSLの問い合わせページヘリダイレクトする設定にしておきます。
外部PHPで問い合わせページを表示する
以下のコードでWordpressの特定のページを取得することができます。 ファイルを作成して動作を確認します。
require_once(dirname(__FILE__). '/../wp-blog-header.php'); // フォームの固定ページデータ取得してメインループにセット // ※ページタイトルなどが有効になりサイドバーの処理もうまくいく $pageFormSlug = 'form-en'; $pageForm = get_page_by_path($pageFormSlug); // ID取得のために先にページデータを取得しています。 $pid = $pageForm->ID; $argsPage = array('page_id' => $pid ); query_posts( $argsPage ); // WPヘッダ読み込み get_header(); // コンテンツHTML出力 get_footer();
wp-configの設定
WordPressのディレクトリ設定などをSSL有り無しの場合それぞれに設定します。
if(false === strpos($_SERVER['HTTP_HOST'], 'shared.example-server.com')){
// SSLなし
define("WP_SITEURL", "http://". $_SERVER['HTTP_HOST']);
define("WP_CONTENT_URL", "http://". $_SERVER['HTTP_HOST']. "/wp-content");
// マルチサイト ※マルチサイトの場合はSSL無しの場合だけ設定
define ('WP_ALLOW_MULTISITE', true);
define( 'MULTISITE', true );
define( 'SUBDOMAIN_INSTALL', false );
//$base = '/';
define( 'DOMAIN_CURRENT_SITE', 'example.com' );
define( 'PATH_CURRENT_SITE', '/' );
define( 'SITE_ID_CURRENT_SITE', 1 );
define( 'BLOG_ID_CURRENT_SITE', 1 );
}else{
// 共用SSL
// wp_homeは設定しない ※CSSなどで利用するtemplate_uriが書き換えられないため
define('WP_SITEURL','https://shared.examle-server.com/~shared-ssl-directory');
define('WP_CONTENT_URL','https://shared.examle-server.com/~shared-ssl-directory/wp-content');
$_SERVER['HTTPS'] = 'on';
$_ENV['HTTPS'] = 'on';
}
/* 編集が必要なのはここまでです ! WordPress でブログをお楽しみください。 */
共用SSLのサブディレクトリを付与する
functions.phpに以下のフィルターを追加します。SSLページの場合、home_urlにサブディレクトリを付与します。
// 共用SSLで実行時のhome_urlを設定
if(false !== strpos($_SERVER['HTTP_HOST'], 'shared.example-server.com')){
function set_shared_ssl( $string ) {
return str_replace( 'https://example.com', 'https://shared.example-server.com/~shared-ssl-directory/', $string );
}
add_filter( 'home_url', 'set_shared_ssl', 1, 4 );
}
SSL有り無しのリダイレクト
htaccessで、SSLページへのリダイレクトを行います。以下の例では.htaccessで「contact-us」というページだけSSL表示します。
#redirect RewriteEngine On RewriteCond %{HTTPS} off RewriteCond %{HTTP_HOST} ^example\.com [NC] RewriteCond %{REQUEST_URI} ^/contact-us/.*$ [NC] RewriteRule ^.*$ https://shared.example-server.com/~shared-ssl-directory/contact-us/ [R=301,L] RewriteCond %{REQUEST_FILENAME} !^(.*)\.(jpg|png|css|js|gif)$ [NC] RewriteCond %{HTTP_HOST} ^shared\.example-server\.com [NC] RewriteCond %{REQUEST_URI} !(.*/contact-us/.*$) [NC] RewriteRule ^(.*)$ http://example.com/$1 [R=301,L]
検索のキーワード文字列がURLエンコードされる
SSLページで検索フォームにキーワードを入力すると、検索実行時にSSL無しのサイトへリダイレクトします。しかし、もとのSSL無しサイトに戻る際にキーワードがURLエンコードされたまま検索されてしまう不具合がありました。
これについては、簡単なプラグインを作成して以下のフィルターを実行することで回避できました。
// 問い合わせフォームページの検索フォームで検索すると、キーワードがURLエンコードされてしまうのでデコード function modify_search_keyword($request) { if(!empty($request['s'])) { $keyword = urldecode($request['s']); $keyword = str_replace(' ', ' ', $keyword); $request['s'] = $keyword; } return $request; } add_filter('request', 'modify_search_keyword', 1);
以上のような手順で共用SSLで問い合わせページを表示することが可能になります。テストは入念に行ってください。
補足ですが、多言語サイトで複数のフォームがある場合それぞれのテーマに切り替えたい場合も、前述の簡単なプラグインにフィルターを追加することで対応可能です。
function switch_theme($theme) { switch(true){ case get_current_blog_id() == 3: // マルチサイトの場合はブログごとに切り替えも可能です。 case false !== strpos($_SERVER['REQUEST_URI'], 'contact-us-en'): $themeName = 'exmaple_theme_en'; break; default: $themeName = $theme; break; } return $themeName; } // 先にマルチ・デバイス・スイッチャーなどテーマを変更するプラグインが動作している場合は上書きできるよう実行順を設定 add_filter( 'template', 'switch_theme', 30 ); add_filter( 'stylesheet', 'switch_theme', 30 );
共用SSLではなく、なるべく独自ドメインでのSSL化を実行することが目標ですが、どうしても共用サーバで問い合わせフォームをSSL化しなくてはいけない・・・という状況もうまく切り抜けることができました。イレギュラーなケースですので同じ問題に取り組んでいる方用の備忘録とします。
提案段階で「共用SSL」は独自ドメインSSL以外では利用しない方向がベストです。企業サイトの場合は、決して共用サーバを利用しない方向で決定していただければ幸いです。