WordPress Logo WordPress のログイン状態を JavaScript で判定する方法

JavaScript を使ってログイン状態(現在ログインしているかどうかや管理者としてログインしているか)を判定する方法について。

更新日:2024年08月11日

作成日:2024年08月11日

PHP の場合

PHP の場合であれば、WordPress が用意している関数(テンプレートタグ) is_user_logged_in() で現在ログインしているかどうかを簡単に判定することができます。

<?php
  // ユーザーがログインしていれば
  if (  is_user_logged_in() ) {
    // 現在ログイン中のユーザーのオブジェクトを取得
    $user = wp_get_current_user();
    // ニックネームが取得できれば 'Hello ' に続けてニックネームを表示
    if($user && $user->user_nicename) {
      echo '<p>Hello '. $user->user_nicename .'!</p>';
    }
  }
?>;

current_user_can() を使えば、ログインしているユーザーの権限なども判定することができます。

<?php
  // 管理者(設定の管理権限があるユーザー)としてログインしていれば
  if (is_user_logged_in() && current_user_can('manage_options')) {
    echo '<p>管理者としてログインしています。</p>';
  }
?>

JavaScript で判定

JavaScript を使って WordPress に現在ログインしているかどうかを判定する方法です。

以下では、テーマフォルダ内に js というフォルダを作成し、その中に確認用の login-status.js という JavaScript ファイルを作成して functions.php で読み込みます。

function add_my_login_status_script() {
  // 確認用の JavaScript ファイルの読み込み
  wp_enqueue_script(
    'login-status',
    get_theme_file_uri( '/js/login-status.js' ),
    array(),
    filemtime( get_theme_file_path( '/js/login-status.js' ) ),
    true
  );
}
add_action( 'wp_enqueue_scripts', 'add_my_login_status_script' );

JavaScript を使って現在ログインしているかどうかを判定する方法を検索すると以下のような方法が見つかります。

  • body_class() が出力するクラスで判定
  • ログインしている時に表示される 管理バーの有無で判定

上記の方法は比較的簡単に判定が可能ですが、サイトによっては判定できない場合もあります。より確実に判定するには AJAX や wp_add_inline_script() などを使う方法があります。

以下それぞれの方法について。

body_class() の出力クラスで判定

テーマで body 要素に body_class() を使ってクラスを出力している場合、例えば以下のようなクラスが body 要素に出力され、ログインしている場合は logged-in クラスが含まれます。

<body class="post-template-default single single-post postid-2560 single-format-standard logged-in admin-bar no-customize-support">

そのため以下のように body 要素のクラスに logged-in が含まれているかどうかを調べれば現在ログインしているかどうかを判定できます。

if ( document.body.classList.contains( 'logged-in' ) ) {
  // ログインしている場合の処理
  console.log('Logged In!');
} else {
  // ログインしていない場合の処理
  console.log('Not Logged In.');
}

但し、この方法の場合、テーマで body 要素に body_class() が記述されていないと利用できません(ほとんどのテーマでは記述されているとは思いますが)。

また、管理者としてログインしているかなどは判定できません。

管理バーの有無で判定

デフォルトではログインしているときには、上部に以下のような管理者用のツールバー(管理バー)が表示されるので、その有無で判定する方法です。

管理バーは以下のように id="wpadminbar" の div 要素として出力されています。

<div id="wpadminbar" class="nojq nojs">
  <div class="quicklinks" id="wp-toolbar" role="navigation" aria-label="ツールバー">
    ・・・中略・・・
  </div>
</div>

そのため以下のように id="wpadminbar" の要素があるかどうかでログインしているかどうかを判定することができます。

if (document.getElementById('wpadminbar')){
  // ログインしている場合の処理
  console.log('Logged In!');
} else {
  // ログインしていない場合の処理
  console.log('Not Logged In!');
}

この方法の場合、テーマで body_class() が使われていなくてもログインを判定できます。

但し、以下のように[ユーザー] → [プロフィール]で「サイトを見るときにツールバーを表示する」のチェックを外してツールバーを非表示にしていたり、

functions.php に以下が記述されている場合は管理バーは表示されないためこの方法で判定できません。

// ツールバーを非表示に
add_filter( 'show_admin_bar', '__return_false' );

また、前述の body_class() の出力クラスで判定する方法と同様、管理者としてログインしているかなどは判定できません。

AJAX を使って判定

AJAX を使えば、body_class() を使っていないサイトや管理バーを非表示にしている場合でも、ログイン状態や管理者としてログインしているかなども判定することができます。

但し、記述が複雑になります。単にログイン状態を検出するだけであれば、ほぼ同様のことを wp_add_inline_script()wp_body_open を使ってもっと簡単に行うことができます。

以下は AJAX を使ってログイン状態を判定する例です。

例えば、これまでの例同様、確認用の JavaScript ファイル js/login-status.js に AJAX の処理を記述する場合、functions.php に以下を記述します。

WordPress の場合、AJAX のリクエストは /wp-admin/admin-ajax.php に送信します。

そのため、AJAX を記述した JavaScript ファイルの登録の際に、wp_add_inline_script() を使って AJAX のリクエスト送信先の URL と nonce の値をページの script タグに出力します。

function add_my_login_status_script() {
  wp_enqueue_script(
    'login-status',
    get_theme_file_uri( '/js/login-status.js' ),
    array(),
    filemtime( get_theme_file_path( '/js/login-status.js' ) ),
    true
  );

  // AJAX のリクエスト送信先 URL と nonce を出力
  wp_add_inline_script(
    // 上記 JavaScript のハンドル名
    'login-status',
    // script タグに以下のインライン JavaScript を出力(変数名 my_ajax_params に設定したオブジェクト)
    'const my_ajax_params = '.json_encode( array(
      'ajaxurl' => admin_url('admin-ajax.php'),
      'my_ajax_nonce' => wp_create_nonce('my-ajax-nonce'),
    )),
    // 上記内容の script タグを JavaScript の読み込みの前に出力
    'before'
  );
}
add_action( 'wp_enqueue_scripts', 'add_my_login_status_script' );

上記の11〜21行目では wp_add_inline_script() を使って、 login-status.js の script タグの直前に AJAX のリクエスト送信先 URL と nonce をインラインスクリプトで出力しています。

上記の場合、ソースコードを確認すると以下のような出力になっています。

以下の2行目は、上記の15〜18行目による出力です。これにより JavaScript ファイル(login-status.js)では my_ajax_params.ajaxurl でリクエスト送信先 URL を、my_ajax_params.my_ajax_nonce で nonce にアクセスできます。

<script id="login-status-js-before"><!-- 出力されたインラインスクリプト -->
const my_ajax_params = {"ajaxurl":"http:\/\/localhost\/wp-sample\/wp-admin\/admin-ajax.php","my_ajax_nonce":"1bb9f9ed9b"}
</script>
<script src="http://localhost/wp-sample/wp-content/themes/my-theme/js/login-status.js?ver=1723277899" id="login-status-js"></script><!-- login-status.js の script タグ -->

また、functions.php には AJAX ハンドラと AJAX アクションの登録を記述します。

以下の例では、リクエストがあったら is_user_logged_in() と current_user_can() でログイン状態とユーザーが管理者かどうかを取得して wp_send_json() でレスポンスとして JSON を返しています。

AJAX ハンドラの定義ではすべてのタスクを完了したら wp_die() で終了する必要がありますが、wp_send_json() を使用している場は自動的に終了処理されるので省略できます。

// AJAX ハンドラの定義(WordPress 側の処理)
function login_status_ajax_handler() {
  // nonce の値を検証
  check_ajax_referer('my-ajax-nonce');
  // リクエストされたら返すデータ
  $data = [
    // ユーザーのログイン状態
    'loggedin' => is_user_logged_in(),
    // ログインしているユーザーが管理者かどうか
    'isAdminUser' => current_user_can('manage_options'),
  ];
  // $data を JSON に変換して返す
  wp_send_json($data);
}

// 上記 AJAX ハンドラを AJAX アクションに登録
$action_name = 'login_status_action';  // アクション名
add_action('wp_ajax_' . $action_name, 'login_status_ajax_handler');
add_action('wp_ajax_nopriv_' . $action_name, 'login_status_ajax_handler');

以下は JavaScript です。送信するデータ(data)のキー action にアクション名を、キー _ajax_nonce に nonce の値を指定したクエリパラメータを含めて送信します。

// 送信するデータ(オブジェクト形式のパラメータ)
const data = {
  // キー名に action を指定し、値にアクション名を指定
  action: "login_status_action",
  // nonce(キー名に _ajax_nonce を指定し、値にインライン script に出力された nonce を指定)
  _ajax_nonce: my_ajax_params.my_ajax_nonce,
};
const xhr = new XMLHttpRequest();
xhr.responseType = "json";
// リクエスト先 URL は my_ajax_params.ajaxurl
xhr.open("POST", my_ajax_params.ajaxurl);
xhr.addEventListener("readystatechange", () => {
  if (xhr.readyState === 4) {
    if (xhr.status >= 200 && xhr.status < 300) {
      // レスポンスの loggedin と isAdminUser が true であれば
      if (xhr.response.loggedin && xhr.response.isAdminUser) {
        // 管理者としてログインしている場合の処理
        console.log('管理者としてログインしています。');
      }else{
        // 管理者としてログインしていない場合の処理
        console.log('管理者としてログインしていません。');
      }
    } else {
      // AJAX リクエストが失敗した場合
      console.log(`AJAX リクエスト失敗: ${xhr.status} (${xhr.statusText})`);
    }
  }
});
// 引数にリクエストボディ(data の URLSearchParams)を指定して送信
xhr.send(new URLSearchParams(data));

関連ページ

wp_add_inline_script() を利用

wp_add_inline_script() を利用すると、wp_enqueue_script() で登録された JavaScript の前後に script タグでインラインの JavaScript コードを出力することができ、PHP 側から JavaScript にデータを渡すことができます。

前述の AJAX の例では AJAX のリクエスト送信先 URL と nonce を出力して、その情報を使って AJAX リクエストを送信してしますが、単にログイン状態を検出するだけであれば冗長です。

functions.php に以下を記述することで、is_user_logged_in() と current_user_can('manage_options') の結果を login-status.js の読み込みの前にインラインスクリプトで出力できます。

function detect_login_status() {
  wp_enqueue_script(
    'login-status',
    get_theme_file_uri( '/js/login-status.js' ),
    array(),
    filemtime( get_theme_file_path( '/js/login-status.js' ) ),
    true
  );

  // ユーザーのログイン状態を表すオブジェクトをインラインで出力
  wp_add_inline_script(
    // 上記 JavaScript のハンドル名
    'login-status',
    // script タグに以下のインライン JavaScript を出力(変数名 login_status に設定したオブジェクト)
    'const login_status = '.json_encode( array(
      // ユーザーのログイン状態
      'isLoggedIn' =>  is_user_logged_in(),
      // ログインしているユーザーが管理者かどうか
      'isAdminUser' => current_user_can('manage_options'),
    )),
    // 上記内容の script タグを JavaScript の読み込みの前に出力
    'before'
  );
}
add_action( 'wp_enqueue_scripts', 'detect_login_status' );

上記により以下の script タグが出力されるので、

<script id="login-status-js-before">
const login_status = {"isLoggedIn":true,"isAdminUser":true}
</script>
<script src="http://localhost/wp-sample/wp-content/themes/my-theme/js/login-status.js?ver=1723336161" id="login-status-js"></script>

login-status.js から出力されたオブジェクトのプロパティ(login_status.isLoggedIn と login_status.isAdminUser)にアクセスしてログイン状態を取得することができます。

if(login_status) {
  if(login_status.isLoggedIn && login_status.isAdminUser) {
    // 管理者としてログインしている場合の処理
    console.log('管理者としてログインしています。')
  }else{
    // 管理者としてログインしていない場合の処理
    console.log('管理者としてログインしていません。')
  }
}

wp_body_open を利用

以下はバージョン5.2 で導入された wp_body_open アクションを利用する例です。

但し、wp_body_open アクションを利用するには、テーマの header.php などのテンプレートに wp_body_open() が記述されている必要があります。

<body <?php body_class(); ?>>
<?php wp_body_open(); ?>

functions.php に読み込む JavaScript の登録と、wp_body_open アクションを記述します。

以下の18行目では、is_user_logged_in() と current_user_can('manage_options') の結果をインラインの CSS(display:none)で非表示に設定した div#logged-in-status のカスタムデータ属性に設定して出力しています。

function add_detect_login_status_script() {
  wp_enqueue_script(
    'login-status',
    get_theme_file_uri( '/js/login-status.js' ),
    array(),
    filemtime( get_theme_file_path( '/js/login-status.js' ) ),
    true
  );
}
add_action( 'wp_enqueue_scripts', 'add_detect_login_status_script' );

add_action( 'wp_body_open', function() {
  // is_user_logged_in() が true であれば yes、false であれば no
  $isLoggedIn = is_user_logged_in() ? 'yes' : 'no';
  //  current_user_can('manage_options') が true であれば yes、false であれば no
  $isAdminUser = current_user_can('manage_options') ? 'yes' : 'no';
  // 上記の結果を非表示の div#logged-in-status  のカスタムデータ属性に設定して出力
  echo '<div style="display:none" id="logged-in-status" data-is-logged-in="' . $isLoggedIn . '" data-is-admin-user="' . $isAdminUser . '"></div>';
});

上記により、例えば以下のように id が logged-in-status の非表示の要素が出力されます。

<div style="display:none" id="logged-in-status" data-is-logged-in="yes" data-is-admin-user="yes"></div><div id="page" class="site">

JavaScript では id が logged-in-status の要素の dataset プロパティ( data-* 属性 を含むオブジェクト)を取得して、その値によりログイン状態を判定しています。

//id が logged-in-status の要素の dataset プロパティを取得
const loggedInStatus = document.getElementById('logged-in-status').dataset;

if(loggedInStatus) {
  if(loggedInStatus.isAdminUser === 'yes' && loggedInStatus.isLoggedIn === 'yes'){
    // 管理者としてログインしている場合の処理
    console.log('管理者としてログインしています。')
  }else{
    // 管理者としてログインしていない場合の処理
    console.log('管理者としてログインしていません。')
  }
}