またWordPressのTips兼メモ書きです。いま色々と制作している途中なので、あと一週間はメモ書きが続きます。Web興味ない人に呆れられてて悲しいです。
タイトルに特に意味はありませんが、特定の年齢層に響くかと思ってこれにしました。
WordPressでSSLを導入するケース
だいたい以下の2パターンあります。今回のエントリーでは僕のように少ない人的・金銭的リソースで会員制サービスを行っている人に向けた情報を記載します。
管理画面(と公開画面のごく一部)だけ保護すればよい
これはよくあるケースだと思うのですが、WordPressを企業用CMSとしてカスタマイズした場合などに当てはまります。この場合、SSLで通信を保護する対象は「ユーザーが使うお問い合わせフォーム」と「管理者が使う管理画面」ぐらいでしょう。これに関しては大して難しいことはなくて、Admin SSLなどのプラグインを使えば実現できます。
公開画面に保護すべきページが沢山ある
このケースは1番目のケースと同じくプラグインで対応できる場合もありますが、僕のように無謀にも会員制サイトを作っていて、ユーザーデータに紐づいたページ(マイページなど)が沢山ある場合はある程度WordPressの中の仕組みに詳しくなっておいた方がいいと思います。
上記の場合、すべてのページを自分で作っているとは限らなくて、なんらかのプラグインによってページやURLが生成されるケースもあると思います。そのプラグインがSSLへの対応をしていないと困ったことになってしまうので、自力で直せるようにしておきましょう。今回の記事はほとんどこっちのケースです。
管理画面・ログインのSSLを有効にする
自分でSSLを設定する場合はwp-config.phpに以下を記載してください。どちらかでもいいですし、両方書いても特に問題はありません
//管理画面はSSLじゃないと駄目という設定 define('FORCE_SSL_ADMIN', true); //ログイン画面はSSLじゃないと駄目という設定 define('FORCE_SSL_LOGIN', true);
会員制サイトにおける共有SSLと独自SSL
これはWordPress自体の問題ではないのですが、多くのWPerは共有サーバ上で走っていることと思います。どこのレンタルサーバも「共有SSL」というものを用意しています。たとえばこのサイトは以前さくらのレンタルサーバを使っていたのですが、そのときの共有SSLのURLは http://xxx.sakura.ne.jp/main でした。要するに、ドメインが変わっちゃうんですね。
WordPressのログイン情報はクッキーを利用しており、基本的に別ドメインのクッキーを読み取ることはブラウザの仕様上できません。読み取れたら、それはブラウザとして欠陥があります。
それでもなんとかログイン情報を取得して動かすことはできるのですが、ちょっとハックっぽいことをしないと動かないので、もし会員情報必須でSSLも必要なのであれば、きちんと独自SSLをとることをお勧めします。ハックするコストを考えると、素直に独自SSLにしちゃった方が楽だったりしますからね。サーバ証明書もホスティング代金もだいぶ安くなっているので、検討してみてください。
サーバ種別 | サービス名称 | サーバ費用(月額) | 独自SSL費用(年額) | 設定方法 |
---|---|---|---|---|
レンタルサーバ | ヘテムル | 1,500円 | 18,000円 | 管理画面から申し込み |
VPS | さくらVPS | 980円〜 | 2,000円〜 | 黒い画面でカタカタコマンドを打って設定 |
他にもCoreServer.jpとかも独自SSLを使えるみたいですね。ちなみに僕のサイトは最近さくらVPS512に引っ越して、SSLボックスで買った2,000円の証明書を使ってます。nginxにしたら早くなったし、年額もこれまでと大して変わらなくて嬉しいですよ。
公開画面をSSLにして注意すべきこと
このサイトではお問い合わせなどがそうなのですが、注意すべきことが幾つかあります。
SSLで保護されたページの中にSSLで保護されていない画像やCSSなどを読み込むと警告が出ます。SafariとかFirefoxだとあまり気づかないですが、IEだとアラートが出てしまうので、詳しくないユーザーがビビって逃げちゃうんですね。
SSLページで読み込むべきでない外部サービスは表示しない
SSLで保護されたページにおいて画像等を読み込む場合は同様にSSLで保護されている必要があります。WordPressにはこの機能がきちんと備わっていて、たとえばスタイルシートなどは自動でURLが書き変わります。
bloginfo('stylesheet_url'); //通常 //→ https://takahashifumiki.com/wp-content/themes/takahashifumiki/style.css //ページがSSLのとき //→ https://takahashifumiki.com/wp-content/themes/takahashifumiki/style.css
WordPress内部のコンテンツはこれで大丈夫なのですが、駄目なのが外部APIを使っている場合です。たとえば、このサイトだとTwitterウィジェットやInstagramなどがそれにあたります。これは相手が対応してくれないことにはどうしようもないので、対応するまでは表示しないようにしましょう。ログイン画面にTwitterウィジェットなくても困らないですからね。
WordPressは現在のページがSSLかどうかを判定する関数を持ってますので、それを使えばいいでしょう。
//SSLじゃないときだけサイドバーを読み込む if(!is_ssl()){ get_sidebar(); }
このサイトでは二段あるフッターの一段目を外部サービスでまとめ、SSL時に非表示にするようにしました。
ちなみに、Google系のサービス(Analyticsとか、Google+とか)はわりかしSSLに対応しています。お金持ちだからでしょう。GravatarとかWordPress.comのサービスもちゃんとSSL対応してますね。Automaticもお金がたまってきたんでしょうか。
投稿内のURLは自動で書き変わらないので書き換える
たとえばこのサイトのように「お問い合わせ」をSSLにして、その投稿内に画像を挿入したとしましょう。そうすると、こういうソースが投稿に入ると思います。
<img src="https://takahashifumiki.com/wp-content/uploads/2011/10/hoge.jpg" />
このSRC属性がSSLのとき不味いので、こんなフックをfunctions.phpに書きます。
/** * SSLのコンテンツが表示されているときにsrcなどを修正する * @param string $content * @return string */ function _replace_ssl_content($content){ if(is_ssl()){ $upload_dir = wp_upload_dir(); $upload_dir_url = $upload_dir['baseurl']; $upload_dir_ssl_url = str_replace('http:', 'https:', $upload_dir_url); $content = str_replace($upload_dir_url, $upload_dir_ssl_url, $content); } return $content; } add_filter('the_content', '_replace_ssl_content');
WordPressのアップロード機能を使って保存されたファイルのURLはhttpsに上書きするというものですね。
リンクがすべてhttpsになるのを書き換える
一度SSLを有効にするとわかるのですが、公開ページでSSLを有効にすると、WordPressの出力するリンクがすべてhttpsになってしまいます。
このサイトでいえば、タグクラウドとか、カテゴリーメニューとか、ページメニューとかが全部httpsになってしまうんですね。基本的にSSL通信は負荷が高いので、必要のないところでは無効にしておきたいところです。
この原因はなにかというと、WordPressのルートURLを返す関数home_urlがSSL通信のときにhttpsでURLを返すことです。リンク出力系の関数はほとんどこの関数を使っているので、全部httpsになってしまうという寸法ですね。
スタイルシートやJavaScript、画像等はSSLのままでもいいのですが、トップページへのリンクまでhttpsに変わるのは困るという問題を解決するためには、こんなものをfunctions.phpに書いておきます。
/** * SSLページですべてのリンクがHTTPSになってしまうのを修正する * @param string $url * @param string $path * @param string $orig_scheme * @return string */ function _ssl_home_url($url, $path = '', $orig_scheme = 'http'){ if(is_ssl() && strpos($path, 'wp-content') === false){ $url = str_replace('https:', 'http:', $url); } return $url; } add_filter('home_url', '_ssl_home_url');
アップロードディレクトリを変更している場合とかは駄目かもしれませんが、僕のサイトはこれで直りました。
SSLに対応していないプラグインの挙動を修正する
これはどんなプラグインを使っているかによるため、漠然としたことしか言えないのですが、プラグインによってはすべてのページで外部のJavascriptを書き込んだり、リンクのURLを書き換えるものがあります。こうした「お行儀の悪いプラグイン」の後始末をすることが必要になるケースがあります。幾つか具体例を上げます。
Theme My Loginの場合
このサイトではTheme My Loginというプラグインを使っています。このプラグインは公開側でオリジナルのログイン画面を作れる機能を持っており、wp_login_url(ログイン画面へのリンクを出力するテンプレートタグ)を書き換える機能を持っているのですが、SSLには対応していません。ソース上は「ここでFORCE_SSL_LOGINをチェック」と書いてあるのですが、実際はチェックしていないんですね。なので、こんな風に修正する必要がありました。
/** * SSLが有効な場合はURLをhttpsにして返す * @param string $url * @return string */ function _my_login_ssl($url){ if(FORCE_SSL_LOGIN || FORCE_SSL_ADMIN){ $url = str_replace('http:', 'https:', $url); } return $url; } add_filter('login_url', '_my_login_ssl'); add_filter('register', '_my_login_ssl'); add_filter('logout_url', '_my_login_ssl'); /** * Theme My Loginが出力する管理画面へのURLをSSLにする * @param string $url * @param string $action * @param int|string $instance * @return string */ function _my_admin_ssl($url, $action = 'login', $instance = ''){ switch($action){ case 'login': case 'register': case 'lostpassword': case 'retrievepassword': case 'resetpass': case 'rp': if(FORCE_SSL_LOGIN || FORCE_SSL_ADMIN){ $url = str_replace('http:', 'https:', $url); } break; default: if(FORCE_SSL_ADMIN){ $url = str_replace('http:', 'https:', $url); } break; } return $url; } add_filter('tml_action_url', '_my_admin_ssl');
Disqusの場合
コメントフォームをソーシャル化してくれるDisqusですが、これもSSLに対応していないJSをすべてのページで読み込んでしまうため、Javascriptの書き込みを削除しなくてはなりません。「どこでJavascriptを書き込んでいるか」を見つけるには、プラグインが出力したであろうソースをコピペしてフォルダ内検索するのがお手軽です。
/** * DisqusのスクリプトがSSLでも読み込まれるのを防止 * @return void */ function _my_remove_disqus(){ if(is_ssl()){ remove_action('wp_footer', 'dsq_output_footer_comment_js'); } } add_action('wp_footer', '_my_remove_disqus', 1);
というわけで、利用しているプラグインによっては作業が増えたりするので、SSLを導入する場合は注意してください。
次回予告
というわけでSSLの設定についてあれこれ書いてきましたが、これでようやくFacebookページとWordPressの連携に着手できそうです。FacebookページもSSL必須となるようですし、しっかり設定しておきましょう。「いいねしてくれたら電子書籍あげるよ!」とか、「Facebookアカウントで会員登録orログインできるよ!」という機能を作る予定なので、お楽しみに。僕のFacebookページはこちらです。
[429] [429] Client error: `POST https://webservices.amazon.co.jp/paapi5/getitems` resulted in a `429 Too Many Requests` response: {"__type":"com.amazon.paapi5#TooManyRequestsException","Errors":[{"Code":"TooManyRequests","Message":"The request was de (truncated...)