Successfully reported this slideshow.
We use your LinkedIn profile and activity data to personalize ads and to show you more relevant ads. You can change your ad preferences anytime.
WordPressでログイン必須のコンテ
ンツを作ったときの気付いたこと
アイティーエー株式会社 ゆいち
自己紹介
・Contact Form 7 add confirmって言う、Contact Form 7に確認画面を
作るプラグイン公開してます。
・WordPressを使って、顧客管理とか販売管理とか
ポータルシステムとか作ることが多いです。
...
WordPressにはいくつかのログイン必須の
コンテンツを提供する方法が用意されてい
ますよね
 投稿にパスワード設定
 非公開(ログインしないと見れない)
 後、頑張って自力で実装
とても手軽に使えて便利。
でも
要望によっては対応しきれない、
困ったことがありました。
投稿にパスワード設定の場合
 パスワード保護されるのは、the_content()の部分だけ、
カスタムフィールドなどを駆使してテーマを作っていると、
その部分は見えてしまう。
<div><?php the_content();?></div...
非公開(ログインしないと見れない)
add_action( ‘wp’, ‘mysite_wp’ );
function mysite_wp() {
if ( 隠したいページだったら ) {
if ( ! is_user_logged_in() ...
どちらの場合でもメディアは隠れない
 どちらの機能を使っても、ページに添付されたメディア
は直リンクなので隠せない。
→
→ 隠したい場合は
→ 自力でごりごりしないとだめ
→
http://example.com/wp-content/up...
管理画面を隠す際の注意点
 管理画面を権限によって、隠すのに私はadmin_initフックをよ
く使うのですが、すべてをredirectしてしまうとajaxが動作しな
いプラグインが出てしまうことがあります。
→
→ これだとajaxが動作し...
ざっと整理
 パスワード保護で保護されるのはthe_contentの中身だけ
 非公開の投稿はアクセスするとログインせずにアクセスすると
404エラーになる(当たり前と言えば当たり前
 どちらの方法も、メディアファイルは保護されない。
...
時間があれば画像のログイン必須の実現をさらっと
例えば、secureposts投稿タイプの投稿画面からのアップ
ロードの場合、ログイン必須の画像として扱うようにする
例えばこんな感じ
<IfModule mod_rewrite.c>
RewriteEngine On
RewriteRule ^index.php$ - [L]
RewriteRule (.*) /wp-admin/admin-ajax.php...
/** 制御対象だった場合、アップロード先をsecureフォルダに変更 **/
add_filter( 'upload_dir', 'mysite_upload_dir' );
function mysite_upload_dir( $uplo...
/** メディア上ではどれがセキュアな画像かわからないのでタイトルに[secure]を自動追加 **/
add_filter( 'mysite_secure_file_prefix', 'mysite_secure_file_prefix', ...
/** 本当はREST APIで作り直したいけど、時間が無かったので、とりあえずadmin-ajaxでファイルへのアク
セス **/
add_action( ‘wp_ajax_mysite_secure’, ‘mysite_secure’ );...
ちなみに文中のネコはうちの子です。
おしまい
Upcoming SlideShare
Loading in …5
×

WordPressでログイン必須のコンテンツを作ったときに気付いたこと

1,553 views

Published on

各コンテンツの保護利用時の注意点と
ログインしないと見れない画像の実現方法のサンプル等

Published in: Internet
  • Be the first to comment

  • Be the first to like this

WordPressでログイン必須のコンテンツを作ったときに気付いたこと

  1. 1. WordPressでログイン必須のコンテ ンツを作ったときの気付いたこと アイティーエー株式会社 ゆいち
  2. 2. 自己紹介 ・Contact Form 7 add confirmって言う、Contact Form 7に確認画面を 作るプラグイン公開してます。 ・WordPressを使って、顧客管理とか販売管理とか ポータルシステムとか作ることが多いです。 ・その保守のためにちょっと変わったレンタルサーバーしてます。 アイティーエー株式会社 ハンドル名は「ゆいち」で時々活動してます。 WordPressを利用したお仕事でいつもWordPressに お世話になりまくってます! 他にもプラ グインちょい 上げてます 良かったら声をかけて下さい。
  3. 3. WordPressにはいくつかのログイン必須の コンテンツを提供する方法が用意されてい ますよね
  4. 4.  投稿にパスワード設定  非公開(ログインしないと見れない)  後、頑張って自力で実装
  5. 5. とても手軽に使えて便利。
  6. 6. でも 要望によっては対応しきれない、 困ったことがありました。
  7. 7. 投稿にパスワード設定の場合  パスワード保護されるのは、the_content()の部分だけ、 カスタムフィールドなどを駆使してテーマを作っていると、 その部分は見えてしまう。 <div><?php the_content();?></div> <ul> <?php $hogehoge = get_post_meta($post_id, ’hogehoge’); ?> <li>フィールド1:<?php echo $hogehoge;?> </ul> ここは隠せるけど ここは隠せない → → 隠したい場合は「非公開」を使うか、 → 自力でごりごりしないとだめ →
  8. 8. 非公開(ログインしないと見れない) add_action( ‘wp’, ‘mysite_wp’ ); function mysite_wp() { if ( 隠したいページだったら ) { if ( ! is_user_logged_in() ) { // ログイン画面へ wp_safe_redirect( home_url( ‘wp- login.php?redirect_to=‘ . urlencode(ページURL) ) ); } } } 例えばこんな感じ  ログインせずにアクセスすると404エラーになる(そりゃ そうだ!)ので、自力でログイン画面へ遷移させたい。
  9. 9. どちらの場合でもメディアは隠れない  どちらの機能を使っても、ページに添付されたメディア は直リンクなので隠せない。 → → 隠したい場合は → 自力でごりごりしないとだめ → http://example.com/wp-content/uploads/2017/04/post1.jpg とか直接アクセスすると見えてしまう。
  10. 10. 管理画面を隠す際の注意点  管理画面を権限によって、隠すのに私はadmin_initフックをよ く使うのですが、すべてをredirectしてしまうとajaxが動作しな いプラグインが出てしまうことがあります。 → → これだとajaxが動作しないことがるので → add_action( 'admin_init', 'mysite_admin_init' ); function mysite_admin_init() { if ( ! current_user_can( 'administrator' ) ) { wp_safe_redirect( home_url( '/' ) ); die; } } function mysite_admin_init() { if ( ! current_user_can( 'administrator' ) ) { // admin-ajaxは除く if ( ( defined( 'DOING_AJAX' ) && ( ! DOING_AJAX ) ) || ( ! defined( 'DOING_AJAX' ) ) ) { wp_safe_redirect( home_url( '/' ) ); die; } } } ajaxを除外
  11. 11. ざっと整理  パスワード保護で保護されるのはthe_contentの中身だけ  非公開の投稿はアクセスするとログインせずにアクセスすると 404エラーになる(当たり前と言えば当たり前  どちらの方法も、メディアファイルは保護されない。  管理画面を隠す際はajaxの動作(admin-ajax.php)を考慮す る必要がある。
  12. 12. 時間があれば画像のログイン必須の実現をさらっと 例えば、secureposts投稿タイプの投稿画面からのアップ ロードの場合、ログイン必須の画像として扱うようにする
  13. 13. 例えばこんな感じ <IfModule mod_rewrite.c> RewriteEngine On RewriteRule ^index.php$ - [L] RewriteRule (.*) /wp-admin/admin-ajax.php?action=mysite_secure&path=$1 </IfModule> /wp-content/uploads/secureフォルダを作成して、 .htaccessファイルを設置、このフォルダのアクセスをAPIへ location /wp-content/uploads/secure { return 301 /wp-admin/admin-ajax.php?action=mysite_secure&path=$uri; } nginxなら 本当はREST APIで作り直したいけど、時間が無かったので、とりあえず admin-ajaxでファイルへのアクセス
  14. 14. /** 制御対象だった場合、アップロード先をsecureフォルダに変更 **/ add_filter( 'upload_dir', 'mysite_upload_dir' ); function mysite_upload_dir( $uploads ) { if ( isset( $_REQUEST['action'] ) && 'upload-attachment' == $_REQUEST['action'] ) { // ファイルのアップロード $is_secure = false; if ( isset( $_REQUEST[‘post_id’] ) && ( ‘’ != $_REQUEST[‘post_id’] ) ) { $post = get_post( intval( $_REQUEST[‘post_id’] ) ); if ( ‘secureposts’ == $post->post_type ) { $is_secure = true; } } elseif ( isset( $_REQUEST[‘post’] ) && ( ‘’ != $_REQUEST[‘post’] ) ) { // 投稿編集画面 $post = get_post( intval( $_REQUEST[‘post’] ) ); if ( ‘secureposts’ == $post->post_type ) { $is_secure = true; } } elseif ( isset( $_REQUEST[‘post_type’] ) && ( ‘secureposts’ == $_REQUEST[‘post_type’] ) ) { // 新規投稿画面 $is_secure = true; } // 紐付く投稿あり if ( $is_secure ) { $uploads['subdir'] = '/secure' . $uploads['subdir']; $uploads['path'] = $uploads['basedir'] . $uploads['subdir']; $uploads['url'] = $uploads['baseurl'] . $uploads['subdir']; if ( ! file_exists( $uploads['path'] ) ) { mkdir( $uploads['path'], 0777, true ); } } } return $uploads; } 対 象 の 投 稿 タ イ プ の 編 集 画 面 か を 判 別 パ ス を 変 更
  15. 15. /** メディア上ではどれがセキュアな画像かわからないのでタイトルに[secure]を自動追加 **/ add_filter( 'mysite_secure_file_prefix', 'mysite_secure_file_prefix', 10 , 1); function mysite_secure_file_prefix($prefix) { return '[secure]'; } add_filter( 'wp_insert_attachment_data', 'mysite_wp_insert_attachment_data', 10, 2 ); function mysite_wp_insert_attachment_data( $data, $postarr ) { if ( isset( $_REQUEST['action'] ) && 'upload-attachment' == $_REQUEST['action'] ) { $is_secure = false; if ( isset( $_REQUEST['post_id'] ) && ( '' != $_REQUEST['post_id'] ) ) { $post = get_post( intval( $_REQUEST['post_id'] ) ); if ( 'secureposts' == $post->post_type ) { $is_secure = true; } } elseif ( isset( $_REQUEST['post'] ) && ( '' != $_REQUEST['post'] ) ) { $post = get_post( intval( $_REQUEST['post'] ) ); if ( 'secureposts' == $post->post_type ) { $is_secure = true; } } elseif ( isset( $_REQUEST['post_type'] ) && ( 'secureposts' == $_REQUEST['post_type'] ) ) { $is_secure = true; } if ( $is_secure ) { $data['post_title'] = apply_filters( 'mysite_secure_file_prefix', '' ) . $data['post_title']; } } return $data; } 対 象 の 投 稿 タ イ プ の 編 集 画 面 か を 判 別タイトルを変更
  16. 16. /** 本当はREST APIで作り直したいけど、時間が無かったので、とりあえずadmin-ajaxでファイルへのアク セス **/ add_action( ‘wp_ajax_mysite_secure’, ‘mysite_secure’ ); add_action( ‘wp_ajax_nopriv_mysite_secure’, ‘mysite_secure’ ); function mysite_secure() { if ( is_user_logged_in() === false ) { wp_die( ‘アクセス権がありません。' ); } $path = ABSPATH . $_REQUEST['path']; $filename = basename( $path ); // ファイル名から投稿を抽出 $file_meta_value = substr( $_REQUEST['path'], strpos( $_REQUEST['path'], '/secure/' ) + 1 ); $att_posts = new WP_Query( array( 'post_type' => 'attachment', 'post_status' => 'inherit', 'meta_query' => array( array( 'key' => '_wp_attached_file', 'value' => $file_meta_value ) ) ) ); if ( $att_posts->have_posts() ) { $att_posts->the_post(); $array_meta_data = get_post_meta( get_the_ID(), '_wp_attachment_metadata', true ); $ext = pathinfo( get_attached_file( get_the_ID() ), PATHINFO_EXTENSION ); $filename = substr( get_the_title(), strlen( apply_filters( 'mysite_secure_file_prefix', '' ) ) ) . '.' . $ext; if ( file_exists( $path ) ) { $filetype = wp_check_filetype( $filename ); header( "Content-Type: " . $filetype['type'] ); //$d = new DateTime('now', new DateTimeZone("Asia/Tokyo")); header( 'Content-Disposition: attachment; filename*=UTF-8''' . rawurlencode( $filename ) ); header( "Content-Length: " . filesize( $path ) ); ob_end_clean(); readfile( $path ); } } exit; } 元 の フ ァ イ ル 名 を 取 得 ダウンロード ログインチェック
  17. 17. ちなみに文中のネコはうちの子です。
  18. 18. おしまい

×