【プラグイン無し】最初の数行を表示させて残りは会員限定で閲覧。WordPressの限定コンテンツ

2022-05-29

今回はログインフォーム、限定コンテンツについてまとめました。
何かの理由で会員限定サイト作成用のプラグインを使用できない場合に参考になればと思います。

このページの手順でできること

  • ・プラグインの使用は無し
  • ・コンテンツの最初の数行を少し表示させて、ログインすると閲覧できる会員限定コンテンツページ
  • ・moreタグ以降を限定コンテンツにする
  • ・ログイン情報は全会員共通。(個別にID、パスワードを発行するタイプではありません)
  • ・WordPressのユーザー追加で購読者を登録。こちらをログイン情報として使用
  • ・フォームのソースコードを見てもWordPressのログインURLが分からないようにしたい
  • ・ログアウトしてもWordPressのログイン画面に遷移させない
  • ・管理者以外のダッシュボードへのアクセス禁止。ツールバーは表示させない

WordPress会員限定コンテンツページの作り方

ステップ① WordPressの「ユーザー」で購読者を登録

WordPressの管理画面左側のメニューから「ユーザー」を開きます。新規追加で権限グループを「購読者」にしたユーザーを作成。ここで設定したユーザー名とパスワードが会員に開示するログイン情報になります。

ステップ② ページのテンプレートを作成

限定コンテンツページ用のテンプレートを作ります。

single.phpを複製し、ファイル名をsingle-exclusive.phpで作成。(ファイル名は一例です)
テンプレート用のコードをこんな感じで入れました。

<?php
/**
 * Template Name: 限定コンテンツ
 * Template Post Type: post,page
 */
get_header(); ?>

 

ステップ③ ログインフォームの設置

引き続き、先ほど作成したテンプレートを編集していきます。
ログインしているかどうかで表示を変える条件分岐を入れて、ログインユーザー以外の場合にログインフォームを出す設定にします。
moreタグの前の最初の数行の表示、ログインフォームの設置を行います。
まずは、「the_content();」の部分を編集します。

<?php the_content(); ?>

↓ 下記のコードと差し替えます。

<?php if ( is_user_logged_in() ) : ?>//ログインユーザーの場合
    <?php the_content(); ?>//コンテンツすべて表示
<?php else : ?>//ログインユーザー以外の場合下記のフォームを出す

//moreタグより前の本文表示
<?php 
global $more;    // グローバル変数 $more
$more = 0;       // moreタグより前の本文表示
the_content("");//リンクボタン出さない
?>
   
<p>コンテンツの閲覧にはログインが必要です。ユーザー名とパスワードを入力してください。</p>
<form method="post" action="">
<label for="username">ユーザー名:</label>
<input type="text" name="log" id="username" value="" required>
<label for="login_password">パスワード:</label>
<input type="password" name="pwd" id="login_password" value="" required>
<p><?php $login = $_GET['login']; if ( $login == 'failed' ) { ?>ユーザー名またはパスワードが間違っています。<?php } ?></p>

<input type="submit" value="ログイン" >
<?php wp_nonce_field(); ?>
</form>

<?php endif; ?>

限定ページにログインフォームがある今回のような場合、actionを空にしたため、フォームを動作させるために下記の設定が必要です。テンプレートsingle-exclusive.phpに追加します。

下記を入れることで、フォーム入力後に送信ボタンをクリックすると入力値を持ちながらログインURLでログイン、ログインした状態で元のページに戻ります。

<?php
if(isset($_POST["log"], $_POST["pwd"])) {
  header('Location: ' . wp_login_url(). '?redirect_to='.esc_attr($_SERVER['REQUEST_URI']), true, 307);
}
?>

 

ステップ④ 入力ミスでログイン画面へ遷移させない

入力を間違えるとログインURLに遷移してしまうので、それを防ぐため下記コードをfunction.phpに追加します。
不正ログインにつながるリスクがあるためログインURLを知られないように気を付けます。

//入力ミスでlogin.php にリダイレクトさせたくない場合
add_action( 'wp_login_failed', 'frontend_login_fail' );
function frontend_login_fail( $username ) {
   $referrer = $_SERVER['HTTP_REFERER'];
   if ( !empty($referrer) && !strstr($referrer,'wp-login') && !strstr($referrer,'wp-admin') ) {
      wp_redirect( $referrer . '?login=failed' );
      exit;
   }
}

こちらを参考にさせていただきました。本当にありがとうございます。

ステップ⑤ 購読者のツールバーの非表示、ダッシュボードへのアクセス禁止

このままではWPダッシュボードにアクセスされてしまうので、function.phpに追記が必要です。購読者(subscriber)に対してツールバー非表示、ダッシュボードへアクセス不可に設定します。

//ダッシュボードにアクセスさせない
add_action( 'auth_redirect', 'subscriber_go_to_home' );
function subscriber_go_to_home( $user_id ) {
    $user = get_userdata( $user_id );
    if ( !$user->has_cap( 'edit_posts' ) ) {
        wp_redirect( get_home_url() );
        exit();
    }
}
//ツールバーを表示させない
add_action( 'after_setup_theme', 'subscriber_hide_admin_bar' );
function subscriber_hide_admin_bar() {
    $user = wp_get_current_user();
    if ( isset( $user->data ) && !$user->has_cap( 'edit_posts' ) ) {
        show_admin_bar( false );
    }
}

 

ステップ⑥ 投稿ページの編集

限定ページにしたい投稿ページの編集画面を開き、ページ属性の部分で作成したテンプレートを設定します。

また、限定にするコンテンツの前にmoreタグを入れます。

テキストテキストテキスト(はじめから表示させる本文)
<!--more-->
テキストテキストテキスト(ログインしてから表示させる本文)

 

ステップ⑦ ログアウトボタン作成

ツールバーのログアウトリンクが使えなくなったので、ログアウトボタンを設置します。

例えばこちらを設置すると、ログインURLが知られてしまいセキュリティ的によくありません。

ログインURLが知られてしまうログインボタン
<a href="<?php echo wp_logout_url(); ?>">ログアウト</a>

 

そこで、まず固定ページで「logout」ページに遷移するボタンを作ります。
そこからWordPressログアウトURLへのリダイレクトでログアウトさせたいと思います。

ログアウトボタンはログインユーザーにのみ表示させます。

<?php if ( is_user_logged_in() ) : ?>
<div class="link-btn"><a href="<?php echo esc_url( home_url( '/' ) ); ?>logout">ログアウトする</a></div>
<?php else : ?>
<?php endif; ?>

 

続いて「ログアウトしました」と表示させる固定ページ「page-logout」(例)を作り、ログアウト後にそちらにリダイレクトさせます。

固定ページ「page-logout」にはリダイレクトさせるための下記phpコードを設置します。

<?php
header('Location: ' . wp_logout_url(get_permalink()), true, 301);
?>

 

「本当にログアウトしますか?」の表示を無くすため、function.phpに下記コードを追記します。

//「本当にログアウトしますか?」を挟まずログアウト
add_action('check_admin_referer', 'logout_without_confirm', 10, 2);
function logout_without_confirm($action, $result)
{
    /**
     * Allow logout without confirmation
     */
    if ($action == "log-out" && !isset($_GET['_wpnonce'])) {
        $redirect_to = isset($_REQUEST['redirect_to']) ? $_REQUEST['redirect_to'] : './page-logout';
        $location = str_replace('&amp;', '&', wp_logout_url($redirect_to));
        header("Location: $location");
        die;
    }
}

「./page-logout'」この部分にリダイレクトさせたいページのURLを入れます。

こちらを参考にさせていただきました。

セキュリティおすすめのプラグイン

プラグイン「SiteGuard WP Plugin」を入れてログインURLを変更するなど、セキュリティ対策が大切です。

おわりに

改善する部分はあると思いますが、おおまかな流れは押さえられたのではないかと思います。ログアウトボタン等もっと効率的な方法があるかも?また調べて分かったことがあったら更新します!
セキュリティが脆弱と言われるWordPress。特にログインフォームや限定サイトなどの構築にはいつも以上に注意したいですね。セキュリティを考えるといろいろ工程が増えていきますが、できることはやって少しでもリスクを減らしたいです。