Чи є спосіб використовувати користувачів 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.

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


4

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

Я створив файл під назвою 'wp-load-minim.php' і називаю цей файл замість 'wp-blog-header.php'

Це Woking для 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 () у load-blog-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 core з абсолютних URL-адрес.
Йонас Лундман

2

Увімкнено або вимкнено лише Wordpress. Іноді, але це лише випадково, а не задумом, можна обійтися цим. Але у вашому випадку я не дуже впевнений, чи це можливо.

Замість цього wp-blog-header.phpви можете спробувати завантажувати лише функції WP, включіть wp-load.phpнатомість. Можливо, це допомагає.


wp-blog-header.phpв основному навантаження, wp-load.phpтак що різниці немає ...

2
@Victor: Є різниця. Це позбавляє пожежі, wp();яка насправді є досить дорогою.
хакре

Гаразд, зараз я намагаюся розібратися, що саме wp () робить.

Я зробив кілька тестів, wp-load.phpа не wp-blog-header.phpвсе, здається, працює нормально, але час завантаження такий же.

@Victor: Ви використовуєте годинник під час натискання клавіші F5 або як насправді вимірюєте? :) У будь-якому разі не використовуйте WordPress, якщо вам потрібна рамка. Ви можете спробувати завантажити лише ті функції, які вам потрібні. Але їх потрібно шукати потроху. Просто включіть потрібні вам файли, як, наприклад, для функцій користувача та доступу до бази даних.
хакре

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.