Проверка авторизации пользователя с помощью jQuery
Проверьте атрибут class
для элемента body
: Если тема использует body_class()
, то для вошедших пользователей у элемента body
будет класс с именем logged-in
. Учтите, что эта функция может быть использована и для элемента html
.
Пример с jQuery:
if(jQuery('body').hasClass('logged-in')){
// Сделать что-то
}
Пример на чистом JavaScript:
if (document.body.classList.contains('logged-in')) {
// сделать что-то
}
Вы также можете просто использовать is_user_logged_in()
в качестве условия для подключения или вывода скрипта.

Мне нравится идея просто проверять body на наличие класса logged-in
. Нужно только убедиться, что темы используют body_class();
или get_body_class();
. В противном случае это не самое надежное решение. Хотя я сам использую эти функции в своих темах, так что для меня это хорошее решение. Спасибо за простую идею.

Если вам нужно проверить, авторизован ли пользователь в текущий момент, используйте этот метод. Другие ответы проверяют статус авторизации на момент загрузки страницы, а не в момент выполнения JavaScript. Пользователь мог авторизоваться в другой вкладке, например.
Добавьте этот код в ваш JavaScript:
var data = {
action: 'is_user_logged_in'
};
jQuery.post(ajaxurl, data, function(response) {
if(response == 'yes') {
// пользователь авторизован, выполняем нужные действия
} else {
// пользователь не авторизован, показываем форму входа
}
});
Добавьте этот код в ваш functions.php
:
function ajax_check_user_logged_in() {
echo is_user_logged_in()?'yes':'no';
die();
}
add_action('wp_ajax_is_user_logged_in', 'ajax_check_user_logged_in');
add_action('wp_ajax_nopriv_is_user_logged_in', 'ajax_check_user_logged_in');

WordPress устанавливает его как 'вашсайт.com/wp-admin/admin-ajax.php'. Это URL, на который должны отправляться все AJAX-запросы

Я поместил jQuery.post внутри обработчика кликов jQuery, но это не работает. Есть идеи, как это решить?

В codex сказано, что в последних версиях WordPress это уже определено. Возможно, вы можете определить свою версию ajaxurl с помощью wp_localize_script

URL всегда должен указывать на "domain.com/wp-admin/admin-ajax.php"

Если у кого-то возникает ошибка "ajaxurl is not defined"... http://stackoverflow.com/questions/17710728/how-to-load-ajax-in-wordpress#17713643

@MridulAggarwal Огромное спасибо за это. Действительно, большое спасибо.

Пожалуйста, добавьте body_class() к тегу body в вашем HTML
<body <?php body_class(); ?>>
// ваш HTML-код
</body>
Это добавит класс logged-in
для авторизованного пользователя, после чего вы можете использовать следующий jQuery-код для выполнения вашего кода только для авторизованных пользователей.
if ($('body').hasClass('logged-in')) {
// выполните ваш jQuery-код.
}

Не знаю, почему этот ответ получил минус. Подход полностью валиден. +1

Не понимаю. У меня тот же вопрос. Ответ правильный, но почему минус?

Хм. Возможно, потому что используется jQuery вместо правильного способа (с использованием фильтра и колбэка). Некоторые люди аллергия на jQuery.

Обратите внимание, что ни один из приведенных выше примеров не будет работать надежно, если вы используете плагин кеширования страниц, так как код в теге body будет статичным. Кроме того, существует более простой способ сделать это (без лишних запросов к AJAX, что не оптимально).
Если вы хотите проверять состояние авторизации пользователя с помощью JavaScript, вы можете использовать этот код для установки cookie при входе пользователя и удаления cookie при выходе. Добавьте это, например, в functions.php вашей темы:
function login_function() {
setcookie('wp_user_logged_in', 1, time() + 31556926, '/');
$_COOKIE['wp_user_logged_in'] = 1;
}
add_action('wp_login', 'login_function');
function logout_function() {
unset($_COOKIE['wp_user_logged_in']);
setcookie('wp_user_logged_in', null, -1, '/');
}
add_action('wp_logout', 'logout_function');
Затем в JavaScript можно просто проверить наличие cookie:
if (document.cookie.indexOf('wp_user_logged_in') !== -1) {
// выполнить действия для авторизованного пользователя
} else {
// выполнить действия для неавторизованного пользователя
}

Это действительно довольно просто, надежно и в худшем случае выполняется почти мгновенно после загрузки страницы (если загружать скрипт в подвале без блокировки рендеринга), в отличие от других ответов. Ajax медленный, а зависимость от классов body не сработает при кешировании. Нужно добавить этот cookie в текст Политики использования файлов cookie. Спасибо, Янош.

В качестве дополнения, существует проблема синхронизации стандартных cookies WordPress и новосозданного cookie, доступного для скриптов, но я получил отличный и простой ответ о том, как её решить: https://stackoverflow.com/questions/56208574/setting-script-accessible-cookie-expiry-based-on-wordpress-logged-in-cookie

Еще один пример, если вы хотите использовать его для AJAX-запросов.
// Упрощенный пример... обратите внимание, что все имена/переменные и т.д. в моем классе имеют уникальные названия.
// ...то же самое относится и к обработчику скрипта.
class wpse69814_example
{
public $response;
public function __construct()
{
add_action( 'wp_enqueue_scripts', array( $this, 'enqueue' ) );
add_action( 'wp_enqueue_scripts', array( $this, 'localize' ), 20 );
}
public function enqueue()
{
wp_enqueue_script(
'wpse69814_handler',
plugins_url( 'url/to/file.js', __FILE__ ),
array( 'jquery' ),
filemtime( plugins_dir_path( __FILE__ ).'/path/to/file.js' ),
true
);
}
public function localize()
{
wp_localize_script( 'wpse69814_handler', 'wpse69814_object', array(
'ajaxurl' => admin_url( 'admin-ajax.php' ),
'ajax_nonce' => wp_create_nonce( 'wpse69814_nonce' ),
'action' => 'wpse69814-handler-action',
'data' => array(
'is_user_logged_in' => is_user_logged_in(),
)
) );
}
}

@BrianFegter Может, стоит объяснить (или [отредактировать] это в тексте) почему? :)

Поскольку CDN не аутентифицируется в WordPress, is_user_logged_in
будет закэширован как false в DOM при обращении к источнику. Состояние пользователя должно быть вынесено в отдельный поток без кэширования через XHR при использовании CDN. Подход @Mridul Aggarwal работает, но только с заголовками no-cache в ответе.

Благодаря этой записи и другой публикации я нашел решение своей проблемы. Просто публикую на случай, если кому-то это окажется полезным.
Работает на текущих сайтах WordPress
Этот код проверяет, авторизован ли пользователь, с помощью jQuery. Если пользователь НЕ авторизован, он предотвращает копирование изображений и текста через контекстное меню (правый клик).
$(document).ready(function(){
// если пользователь не авторизован...
if (!document.querySelector('body.logged-in')){
//блокируем весь контент
disableSelection(document.body);
// запрещаем клик по изображениям
$('img').bind('contextmenu', function(e){return false;});
console.log('привет');
}
// функция для блокировки всего контента
function disableSelection(target){
$(function() {
$(this).bind("contextmenu", function(e) {
e.preventDefault();
});
});
if (typeof target.onselectstart!="undefined") //Для IE
target.onselectstart=function(){return false}
else if (typeof target.style.MozUserSelect!="undefined") //Для Firefox
target.style.MozUserSelect="none"
else //Все остальные случаи (Для Opera)
target.onmousedown=function(){return false}
target.style.cursor = "default";
}
})

Я использую альтернативный способ без ajaxurl
и body class
. Я просто не доверяю классу body, который может отсутствовать в некоторых темах.
В файле functions.php
добавьте:
add_action( 'wp_body_open', 'custom_body_open' );
function custom_body_open() {
$logged_in = is_user_logged_in() ? 'yes' : 'no'; //Функция WP для проверки авторизации пользователя
echo '<div style="display:none" class="user_is_logged_in" data-logged-in="' . $logged_in . '" ></div>';
}
Это создаст невидимый div
в начале тега body с:
- Именем класса "user_is_logged_in" - только для ссылки в jQuery.
- Стилем "display: none" - делает div невидимым. Вместо этого можно использовать CSS:
.user_is_logged_in { display: none }
- Значением "data-(logged-in)" - "yes" (авторизован) или "no" (не авторизован). Это значение будет запрашиваться через
jQuery
.
В jQuery я запрашиваю значение "data-logged-in" и действую соответственно:
jQuery(document).ready(function($) {
var logged_in = $(".user_is_logged_in").data("logged-in") == 'yes' ? true : false;
if (logged_in) {
...
}
else {
...
}
}

Вот скрипт для WordPress, который добавит класс в тег Body в зависимости от того, вошел пользователь в систему или нет
https://gist.github.com/raftaar1191/55fe297db0724e62883846b3ed31b543

Я оценил все ответы, но, на мой взгляд, использование локализации скрипта или проверки CSS-класса не является лучшей практикой, так как проверка CSS-класса не на 100% надежна, а функция локализации скрипта, как следует из названия, предназначена для локализации.
После WordPress 4.5 лучшим решением будет добавление встроенного скрипта следующим образом:
<?php
function detect_login() {
$isLoggedIn = is_user_logged_in();
wp_register_script( 'detect_login', '' );
wp_enqueue_script( 'detect_login');
wp_add_inline_script( 'detect_login', "var isLoggedIn = $isLoggedIn" );
}
add_action( 'wp_enqueue_scripts', 'detect_login' );
Затем, очевидно, можно проверить глобальную область видимости, которая, к сожалению, теперь загрязнена нашей глобальной переменной isLoggedIn, следующим образом: window.isLoggedIn

@JacobPeattie Да, причина, по которой они создали wp_add_inline_script()
, — избежать использования функции локализации скриптов для объявления глобальных переменных. Как следует из названия, это более подходящий вариант. Зачем использовать что-то, что изначально не предназначалось для этой цели, если у нас есть хорошая альтернатива?

Это не та причина, по которой он был добавлен. Он был добавлен для поддержки добавления небольших фрагментов исполняемого кода до или после скрипта, чтобы поддерживать такие вещи, как загрузчики шрифтов. https://make.wordpress.org/core/2016/03/08/enhanced-script-loader-in-wordpress-4-5/

@JacobPeattie точно, и для чего вообще добавлялась строка wp_localize_script()
? Чтобы загрязнять глобальную область видимости глобальными переменными? Или действительно для локализации, как предполагает название?

О чем ты говоришь? wp_localize_script заставляет тебя помещать переменные внутри объекта с пространством имен. Твой собственный ответ добавляет переменную в глобальную область видимости без какого-либо пространства имен.

@JacobPeattie хм, а где, по-твоему, будет храниться объект из wp_localize_script()
? подсказка: window
. Впрочем, раз ты так привязан к wp_localize_script()
, можешь и дальше придерживаться своего мнения об использовании его для объявления переменных, не связанных с локализацией, вместо использования нативной функции, созданной именно для этого. Каждому свое.
