Есть ли способ использовать пользователей Wordpress, но без загрузки всего ядра Wordpress?


11

У меня есть сайт Wordpress и веб-приложение, которое могут использовать только зарегистрированные пользователи (Wordpress).

Сейчас я загружаюсь, wp-blog-header.phpчтобы проверить, вошел ли пользователь в систему. Все работает нормально, но, поскольку при каждом запросе (включая AJAX) мне также необходимо загрузить ядро ​​Wordpress, это заметно замедляет работу моего приложения (более 70% от общего числа). время загрузки).

Есть ли простой способ использовать пользователей Wordpress, но без загрузки всего ядра Wordpress?

Обновление: мне нужно знать, какой пользователь вошел в систему, а также безопасность важна.

Спасибо!

Ответы:


9

Если бы мне пришлось это сделать, я бы использовал свой собственный файл cookie для определения имени входа и загружал WordPress только для проверки при необходимости.

Файл cookie wordpress_logged_in_ {some-hash} может использоваться для определения пользователя, а WordPress использует его для определения того же самого. Вы не можете легко переопределить это, но вы можете использовать его без загрузки WordPress на несколько запросов.

Например, вот мой хэш cookie (полностью скомпонованный, но реалистичный):

key: wordpress_logged_in_1234567890abcdef1234567890abcdef
value: admin|1234567890|abcdef1234567890abcdef1234567890

То, как WordPress знает, как этот файл cookie действителен, не имеет значения, все, что вам нужно знать, это то, действителен ли он один раз, а затем вы подпишите его секретом.

Итак, впервые пользователь еще не доказал. Вы загружаете wp-load.php, а WP проверяет cookie и регистрирует пользователя. Теперь вы делаете все, что делаете, чтобы доказать себе, что пользователь вошел в систему, затем вы устанавливаете свой собственный cookie. Ключом может быть что угодно, значение, которое вы вводите в дайджест сообщения с секретным ключом с помощью функции hash_hmac.

$key = ... // the key from the WP cookie
$value = ... // the value from the WP cookie
$hash = hash_hmac ( 'md5' , $key.$value , 'some secret key' );

Вы получите обратно тарабарщину, которую вы отправите обратно с помощью setcookie (). При будущих запросах они отправят вам этот файл cookie. Вы можете сначала проверить это и проверить его, используя ту же хеш-функцию и секретный ключ.

Только вы можете генерировать хэш, потому что только вы знаете секретный ключ. Поэтому, если они отправляют обратно действительный хеш, который также совпадает с тем, что они отправляют для своих файлов cookie WP, то вы знаете, что они были проверены с помощью WP, через ваш код и ранее, и вы можете получить имя пользователя прямо из этого значения (это первое часть печенья, очевидно). Тогда вам не нужно загружать WP.

Кстати, секретный ключ должен быть длинным и случайным . Не короткий пароль. Не словарное слово. Просто большой бессмысленный бред. Шум в линии и многое другое. Пример ключа: 'GHY5hFNqq4Ntdu=3:SUp8#/+_W!- @@^@xslN*L|N+Vn;(1xo8jNyp,au$v9Ki5*'


4

Поскольку я также использую некоторые функции Wordpress помимо управления пользователями, я решил продолжить загружать ядро ​​WP, но я создал специальный файл, который загружает только то, что мне нужно, без загрузки плагинов. Новое время загрузки удовлетворительное (оно уменьшилось с 1,5 с при полной загрузке WP до 0,3 с)

Я сделал файл с именем «wp-load -imum.php», и я называю этот файл вместо «wp-blog-header.php»

Это работает для WP 3.3. Вот содержимое файла, если вы считаете его полезным:

<?php

//this stops wp-settings from load everything
define ('SHORTINIT',true);

error_reporting( E_CORE_ERROR | E_CORE_WARNING | E_COMPILE_ERROR | E_ERROR | E_WARNING | E_PARSE | E_USER_ERROR | E_USER_WARNING | E_RECOVERABLE_ERROR );

/** Define ABSPATH as this files directory */
define( 'ABSPATH', dirname(__FILE__) . '/' );

//WP config file
require ('wp-config.php');

if (SHORTINIT):

// Load the l18n library.
require( ABSPATH . WPINC . '/l10n.php' );

// Run the installer if WordPress is not installed.
wp_not_installed();


// Load most of WordPress.
require( ABSPATH . WPINC . '/class-wp-walker.php' );
//require( ABSPATH . WPINC . '/class-wp-ajax-response.php' );
require( ABSPATH . WPINC . '/formatting.php' );
require( ABSPATH . WPINC . '/capabilities.php' );
require( ABSPATH . WPINC . '/query.php' );
require( ABSPATH . WPINC . '/theme.php' );
require( ABSPATH . WPINC . '/user.php' );
require( ABSPATH . WPINC . '/meta.php' );
require( ABSPATH . WPINC . '/general-template.php' );
require( ABSPATH . WPINC . '/link-template.php' );
//require( ABSPATH . WPINC . '/author-template.php' );
require( ABSPATH . WPINC . '/post.php' );
//require( ABSPATH . WPINC . '/post-template.php' );
//require( ABSPATH . WPINC . '/category.php' );
//require( ABSPATH . WPINC . '/category-template.php' );
require( ABSPATH . WPINC . '/comment.php' );
//require( ABSPATH . WPINC . '/comment-template.php' );
require( ABSPATH . WPINC . '/rewrite.php' );
//require( ABSPATH . WPINC . '/feed.php' );
//require( ABSPATH . WPINC . '/bookmark.php' );
//require( ABSPATH . WPINC . '/bookmark-template.php' );
require( ABSPATH . WPINC . '/kses.php' );
require( ABSPATH . WPINC . '/cron.php' );
//require( ABSPATH . WPINC . '/deprecated.php' );
require( ABSPATH . WPINC . '/script-loader.php' );
require( ABSPATH . WPINC . '/taxonomy.php' );
//require( ABSPATH . WPINC . '/update.php' );
//require( ABSPATH . WPINC . '/canonical.php' );
require( ABSPATH . WPINC . '/shortcodes.php' );
require( ABSPATH . WPINC . '/media.php' );
require( ABSPATH . WPINC . '/http.php' );
require( ABSPATH . WPINC . '/class-http.php' );
require( ABSPATH . WPINC . '/widgets.php' );
require( ABSPATH . WPINC . '/nav-menu.php' );
//require( ABSPATH . WPINC . '/nav-menu-template.php' );
//require( ABSPATH . WPINC . '/admin-bar.php' );

// Load multisite-specific files.
if ( is_multisite() ) {
    require( ABSPATH . WPINC . '/ms-functions.php' );
    require( ABSPATH . WPINC . '/ms-default-filters.php' );
    require( ABSPATH . WPINC . '/ms-deprecated.php' );
}

// Define constants that rely on the API to obtain the default value.
// Define must-use plugin directory constants, which may be overridden in the sunrise.php drop-in.
wp_plugin_directory_constants( );

// Load must-use plugins.
/*foreach ( wp_get_mu_plugins() as $mu_plugin ) {
    include_once( $mu_plugin );
}
unset( $mu_plugin );*/

// Load network activated plugins.
if ( is_multisite() ) {
    foreach( wp_get_active_network_plugins() as $network_plugin ) {
        include_once( $network_plugin );
    }
    unset( $network_plugin );
}

do_action( 'muplugins_loaded' );

if ( is_multisite() )
    ms_cookie_constants(  );

// Define constants after multisite is loaded. Cookie-related constants may be overridden in ms_network_cookies().
wp_cookie_constants( );

// Define and enforce our SSL constants
wp_ssl_constants( );

// Create common globals.
require( ABSPATH . WPINC . '/vars.php' );

// Make taxonomies and posts available to plugins and themes.
// @plugin authors: warning: these get registered again on the init hook.
create_initial_taxonomies();
create_initial_post_types();

// Register the default theme directory root
//register_theme_directory( get_theme_root() );

// Load active plugins.
/*foreach ( wp_get_active_and_valid_plugins() as $plugin )
    include_once( $plugin );
unset( $plugin );*/

// Load pluggable functions.
require( ABSPATH . WPINC . '/pluggable.php' );
//require( ABSPATH . WPINC . '/pluggable-deprecated.php' );

// Set internal encoding.
wp_set_internal_encoding();

// Run wp_cache_postload() if object cache is enabled and the function exists.
if ( WP_CACHE && function_exists( 'wp_cache_postload' ) )
    wp_cache_postload();

do_action( 'plugins_loaded' );

// Define constants which affect functionality if not already defined.
wp_functionality_constants( );

// Add magic quotes and set up $_REQUEST ( $_GET + $_POST )
wp_magic_quotes();

do_action( 'sanitize_comment_cookies' );

/**
 * WordPress Query object
 * @global object $wp_the_query
 * @since 2.0.0
 */
$wp_the_query = new WP_Query();

/**
 * Holds the reference to @see $wp_the_query
 * Use this global for WordPress queries
 * @global object $wp_query
 * @since 1.5.0
 */
$wp_query =& $wp_the_query;

/**
 * Holds the WordPress Rewrite object for creating pretty URLs
 * @global object $wp_rewrite
 * @since 1.5.0
 */
$wp_rewrite = new WP_Rewrite();

/**
 * WordPress Object
 * @global object $wp
 * @since 2.0.0
 */
$wp = new WP();

/**
 * WordPress Widget Factory Object
 * @global object $wp_widget_factory
 * @since 2.8.0
 */
$GLOBALS['wp_widget_factory'] = new WP_Widget_Factory();

do_action( 'setup_theme' );

// Define the template related constants.
wp_templating_constants(  );

// Load the default text localization domain.
load_default_textdomain();

// Find the blog locale.
$locale = get_locale();
$locale_file = WP_LANG_DIR . "/$locale.php";
if ( ( 0 === validate_file( $locale ) ) && is_readable( $locale_file ) )
    require( $locale_file );
unset($locale_file);

// Pull in locale data after loading text domain.
require( ABSPATH . WPINC . '/locale.php' );

/**
 * WordPress Locale object for loading locale domain date and various strings.
 * @global object $wp_locale
 * @since 2.1.0
 */
$GLOBALS['wp_locale'] = new WP_Locale();

// Load the functions for the active theme, for both parent and child theme if applicable.
/*if ( ! defined( 'WP_INSTALLING' ) || 'wp-activate.php' === $pagenow ) {
    if ( TEMPLATEPATH !== STYLESHEETPATH && file_exists( STYLESHEETPATH . '/functions.php' ) )
        include( STYLESHEETPATH . '/functions.php' );
    if ( file_exists( TEMPLATEPATH . '/functions.php' ) )
        include( TEMPLATEPATH . '/functions.php' );
}*/

do_action( 'after_setup_theme' );

// Load any template functions the theme supports.
//require_if_theme_supports( 'post-thumbnails', ABSPATH . WPINC . '/post-thumbnail-template.php' );

// Set up current user.
$wp->init();

/**
 * Most of WP is loaded at this stage, and the user is authenticated. WP continues
 * to load on the init hook that follows (e.g. widgets), and many plugins instantiate
 * themselves on it for all sorts of reasons (e.g. they need a user, a taxonomy, etc.).
 *
 * If you wish to plug an action once WP is loaded, use the wp_loaded hook below.
 */
do_action( 'init' );

// Check site status
if ( is_multisite() ) {
    if ( true !== ( $file = ms_site_check() ) ) {
        require( $file );
        die();
    }
    unset($file);
}

/**
 * This hook is fired once WP, all plugins, and the theme are fully loaded and instantiated.
 *
 * AJAX requests should use wp-admin/admin-ajax.php. admin-ajax.php can handle requests for
 * users not logged in.
 *
 * @link http://codex.wordpress.org/AJAX_in_Plugins
 *
 * @since 3.0.0
 */
do_action('wp_loaded');

endif;

//require( ABSPATH . WPINC . '/pluggable.php' );

1
Это хорошая идея. Одно из предложений: вы, вероятно, можете отказаться от загрузки плагина и настроить запрос (конечно, в зависимости от вашего варианта использования).
chrisguitarguy

3

Для Wordpress 4.9: Как я не могу комментировать (новый пользователь). Окончательный вариант (одиночная установка WP), который я использую для создания is_user_logged_in()и current_user_can()работы, описан ниже. Мы require('wp-load.php') первый (пропустить WP () в грузоподъемного блог-header.php) , и получить ABSPATHпостоянную затем вручную включает в себя точно все необходимые вещи.

Использование define('SHORTINIT', true)+ require('wp-load.php')+ вручную включает в себя:

Загрузка страницы: 1,05 сек - включены файлы: 43 файла

Сравнение: используя ТОЛЬКО require('wp-load.php') :

Загрузка страницы: 1,35 сек - включены файлы: 419 файлов

Разница во времени (0,3 сек) может отличаться от установок и PHP-движков, но при проверке большого количества запросов на одной загрузке страницы - все это складывается!

Не забудьте использовать относительный вызов WP установленного каталога. Из директории пользовательских плагинов Wordpress, внутри одного уровня поддиректории, при обычной установке путь должен выглядеть следующим образом:

$wordpress = '../../../../wp-load.php';

Затем:

define('SHORTINIT', true);
include_once $wordpress;

require_once ( ABSPATH . WPINC . '/class-wp-user.php' );
require_once ( ABSPATH . WPINC . '/class-wp-roles.php' );
require_once ( ABSPATH . WPINC . '/class-wp-role.php' );
require_once ( ABSPATH . WPINC . '/class-wp-session-tokens.php' );
require_once ( ABSPATH . WPINC . '/class-wp-user-meta-session-tokens.php' );
require_once ( ABSPATH . WPINC . '/formatting.php' );
require_once ( ABSPATH . WPINC . '/capabilities.php' );
//require_once ( ABSPATH . WPINC . '/query.php' ); // - might be useful
require_once ( ABSPATH . WPINC . '/user.php' );
require_once ( ABSPATH . WPINC . '/meta.php' );

wp_cookie_constants();

require_once ( ABSPATH . WPINC . '/vars.php' );
require_once ( ABSPATH . WPINC . '/kses.php' );
require_once ( ABSPATH . WPINC . '/rest-api.php' );
require_once ( ABSPATH . WPINC . '/pluggable.php' );

После этого проверка пользователя становится доступной. Для другой задачи, при выполнении одного или двух запросов , отслеживание других необходимых файлов может не стоить 0.3 сек. Пропустить SHORTINITпостоянную и вручную загромождать.


+1, чтобы использовать первый вызов как относительный. Вещи могут быть очень грязными, если отдавать wp ядро ​​из абсолютных URL.
Джонас Лундман

2

Только Wordpress включен или выключен. Иногда, но это только случайно, а не по замыслу, вы можете обойти это. Но в твоем случае я не совсем уверен, возможно ли это.

Вместо того, wp-blog-header.phpчтобы пытаться загрузить только функции WP, включите wp-load.phpвместо этого. Может быть, это помогает.


wp-blog-header.phpв основном загружается, wp-load.phpпоэтому нет различий ...

2
@ Виктор: есть разница. Это избавляет от запуска, wp();что на самом деле довольно дорого.
hakre

Хорошо, теперь я пытаюсь выяснить, что именно делает wp ().

Я сделал несколько тестов wp-load.phpвместо wp-blog-header.php, кажется, все работает нормально, но время загрузки такое же.

@Victor: Вы используете свои часы, нажимая F5, или как вы на самом деле измеряете? :) В любом случае, не используйте WordPress, если вам действительно нужен фреймворк. Вместо этого вы можете попытаться загрузить только те функции, которые вам действительно нужны. Но вам нужно искать их постепенно. Просто включите файлы, которые вам действительно нужны, например, для пользовательских функций и доступа к базе данных.
hakre

1

Вы можете попытаться получить доступ к таблице напрямую. Если вы знаете суть файлов паролей, вы можете заставить их войти через вашу собственную систему, подсчитать пароль самостоятельно (посмотрите, как это делает Wordpress) и отслеживать их самостоятельно. Если вам нужна возможность перемещаться между вашей собственной системой и WordPress без повторной аутентификации, вы можете создать плагин для WordPress, который передает текущий сеанс пользователей в вашу систему.


0

Самое быстрое, что вы можете получить с WP - это создание пользовательской оболочки, которая будет определять SHORTINITи загружать ядро. Это остановит загрузку ядра сразу после подключения базы данных и до обработки большинства API и расширений (темы и плагинов).

Оттуда вы можете попытаться получить доступ к базе данных самостоятельно или выборочно загрузить части ядра, которые вам нужны.

Это довольно грязный подход, но он так же близок к меньшей загрузке ядра, как в WP.


SHORTINIT - хороший подход, но это означает, что все функции для проверки пользователей и хешей и тому подобное не будут загружены. Вы могли бы переопределить это, но грязно, как вы сказали.
Отто

@ Otto Наверное, не переопределение, а загрузка этих частей ядра вручную. И если есть какие-либо модификации пользователей, выполняемые плагинами, загружайте их также вручную. Да, это довольно сложный подход. Но следующая альтернатива для повышения производительности - полностью отказаться от WP и работать с базой данных напрямую, что еще более грязно.
Первый


-1

Если вы просто хотите разрешить всем пользователям Wordpress использовать веб-приложение, вы можете использовать систему управления пользователями Wordpress и просто проверить, вошел ли пользователь в систему или нет.

Чтобы проверить это, вам нужно проверить, присутствует ли указанный файл cookie wordpress_logged_in_{some-hash}. Если нет, перенаправьте пользователя на страницу входа в Wordpress. {some-hash}Часть названия печенья просто набор букв и цифр.


1
Мне нужно знать, какой пользователь вошел в систему, а также безопасность важна.

Это кошмар безопасности. Любой может отправить запрос с cookie, который имеет такую ​​структуру. Поскольку вы не проверяете хеш, а просто проверяете, есть ли что-то, это приравнивается к форме входа в систему, где вы можете ввести что-нибудь для пользователя и пароля, если поля не пусты.
kraftner
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.