¿Hay alguna manera de usar los usuarios de Wordpress pero sin cargar todo el núcleo de Wordpress?

11

Tengo un sitio de Wordpress y una aplicación web que solo pueden usar los usuarios registrados (Wordpress).

Ahora estoy cargando wp-blog-header.phppara verificar si el usuario ha iniciado sesión. Todo funciona bien, pero porque en cada solicitud (incluida AJAX) también tengo que cargar el núcleo de Wordpress, ralentiza mi aplicación visiblemente (más del 70% del total Tiempo de carga).

¿Hay alguna forma simple de usar los usuarios de Wordpress pero sin cargar todo el núcleo de Wordpress?

Actualización: necesito saber qué usuario ha iniciado sesión y también la seguridad es importante.

¡Gracias!

Víctor
fuente

Respuestas:

9

Si tuviera que hacer esto, usaría mi propia cookie para determinar el inicio de sesión y solo cargaría WordPress para verificar cuando sea necesario.

La cookie wordpress_logged_in_ {some-hash} se puede usar para determinar el usuario, y WordPress la usa para determinar lo mismo. No puede volver a implementarlo fácilmente, pero puede usarlo sin cargar WordPress en múltiples solicitudes.

Por ejemplo, aquí está mi hash de cookies (datos completamente compuestos, pero realistas):

key: wordpress_logged_in_1234567890abcdef1234567890abcdef
value: admin|1234567890|abcdef1234567890abcdef1234567890

La forma en que WordPress sabe cómo es válida esa cookie es irrelevante, todo lo que necesita saber es si es válida una vez, luego la firma con un secreto.

Entonces, la primera vez, el usuario aún no está probado. Carga wp-load.php y WP valida la cookie e inicia sesión en el usuario. Ahora hace lo que sea para demostrar que el usuario ha iniciado sesión y luego configura su propia cookie. La clave puede ser cualquier cosa personalizada para usted, el valor que convierte en un resumen de mensaje con una clave secreta utilizando la función 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' );

Obtendrá galimatías, que les enviará de vuelta usando setcookie (). En futuras solicitudes, le enviarán esta cookie. Puede verificar eso primero y validarlo usando la misma función hash y clave secreta.

Solo usted puede generar el hash porque solo usted conoce la clave secreta. Entonces, si envían un hash válido que también coincide con lo que envían para su cookie WP, entonces sabrá que han sido validados con WP, a través de su código, antes, y puede obtener el nombre de usuario correcto desde ese valor (es el primero parte de la cookie, obviamente). Entonces no tienes que cargar WP.

La clave secreta, por cierto, debe ser larga y aleatoria . No es una contraseña corta. No es una palabra del diccionario. Solo grandes galimatías sin sentido. Ruido de línea, y mucho. Clave de ejemplo: 'GHY5hFNqq4Ntdu=3:SUp8#/+_W!- @@^@xslN*L|N+Vn;(1xo8jNyp,au$v9Ki5*'

Otón
fuente
4

Como también estoy usando algunas funciones de Wordpress además de la administración de usuarios, decidí continuar cargando el núcleo de WP pero hice un archivo personalizado que carga solo lo que necesito y sin cargar los complementos. El nuevo tiempo de carga es satisfactorio (disminuyó de 1.5s con carga completa de WP a 0.3s)

He creado un archivo llamado 'wp-load-minimum.php' y llamo a este archivo en lugar de 'wp-blog-header.php'

Esto funciona para WP 3.3. Aquí está el contenido del archivo, si lo encuentra útil:

<?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' );
Víctor
fuente
1
Esta es una buena idea. Una sugerencia: probablemente pueda deshacerse de la carga de complementos y la configuración de consultas (dependiendo de su caso de uso, por supuesto).
chrisguitarguy
3

Para Wordpress 4.9: como no puedo comentar (nuevo usuario). La alma final (instalación de WP simple) que uso para hacer is_user_logged_in()y current_user_can()trabajar, es la siguiente a continuación. Nosotros require('wp-load.php') primero (Para saltar wp () en la carga-blog-header.php) , y obtenemos ABSPATHconstante, entonces, incluye manual exactamente todo lo necesario.

Usar define('SHORTINIT', true)+ require('wp-load.php')+ manualmente incluye:

Carga de página: 1.05 sek - archivos incluidos: 43 archivos

Comparando: Usando SOLO require('wp-load.php') :

Carga de la página: 1.35 sek - archivos incluidos: 419 archivos

La diferencia horaria (0.3 sek) puede diferir de las instalaciones y los motores PHP, pero al validar muchas solicitudes en una carga de página, ¡las cosas se suman!

Recuerde usar la llamada relativa al directorio instalado de WP. Desde un directorio de plugin personalizado de Wordpress, dentro de un nivel de subdirección, instalación normal, una ruta debería ser como:

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

Entonces:

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' );

Después de esto, la validación del usuario es accesible. Para otra tarea, ejecutar una o dos solicitudes , rastrear otros archivos necesarios podría no valer 0.3 sek. Omita el SHORTINITdesorden constante y manual.

Anna Ericson
fuente
+1 para usar la primera llamada como relativa, las cosas podrían ser realmente desordenadas si se presta wp core desde urls absolutas.
Jonas Lundman
2

Wordpress solo está activado o desactivado. A veces, pero eso es solo por casualidad y no por diseño, puedes evitarlo. Pero en su caso, no estoy realmente seguro de si es posible.

En lugar de wp-blog-header.phpintentar cargar solo las funciones de WP, incluya en su wp-load.phplugar. Quizás eso ayude.

hakre
fuente
wp-blog-header.phpbásicamente se carga wp-load.phpasí que no hay diferencia ...
2
@Victor: hay una diferencia. Ahorra el encendido, wp();que en realidad es bastante costoso.
Hakre
Bien, ahora estoy tratando de averiguar qué hace exactamente wp ().
He hecho algunas pruebas con, en wp-load.phplugar de wp-blog-header.php, todo parece funcionar bien, pero el tiempo de carga es el mismo.
@Victor: ¿Está usando su reloj mientras presiona F5 o cómo mide realmente? :) De todos modos, no use WordPress si realmente necesita un marco. Puede intentar cargar solo las funciones que realmente necesita en su lugar. Pero debes buscarlos poco a poco. Simplemente incluya los archivos que realmente necesita, como las funciones del usuario y el acceso a la base de datos probablemente.
Hakre
1

Puede intentar acceder a la tabla directamente. Si conoce la sal de los archivos de contraseña, puede hacer que inicien sesión a través de su propio sistema, revise la contraseña usted mismo (vea cómo Wordpress lo hace) y realice un seguimiento de ellos usted mismo. Si desea la capacidad de atravesar su propio sistema y wordpress sin volver a autenticarse, puede hacer un complemento para wordpress que pase la sesión de los usuarios actuales a su sistema.


fuente
0

Lo más rápido que puede obtener con WP es hacer un contenedor personalizado que definirá SHORTINITy luego cargará el núcleo. Esto hará que la carga del núcleo se detenga inmediatamente después de que la base de datos esté conectada y antes de que se procesen la mayoría de las API y extensiones (tema y complementos).

A partir de ahí, puede intentar acceder solo a la base de datos o cargar selectivamente las partes del núcleo que necesita.

Este es un enfoque bastante desordenado, pero está tan cerca de una carga de núcleo más ligera como las cosas se ponen en WP.

Rarst
fuente
SHORTINIT es un buen enfoque, pero esto significa que no se cargarán todas las funciones para verificar los usuarios y los hashes y demás. Podrías volver a implementar eso, pero desordenado, como dijiste.
Otto
@Otto Probablemente no se vuelva a implementar, sino que cargue esas partes del núcleo a mano. Y si hay modificaciones en los usuarios, los complementos se cargan a mano también. Sí, este es un enfoque bastante complicado. Pero la siguiente alternativa para un mejor rendimiento es deshacerse de WP por completo y trabajar con la base de datos directamente, lo que es aún más complicado.
Rarst
-1

Si solo desea permitir que todos los usuarios de Wordpress usen la aplicación web, puede usar el sistema de administración de usuarios de Wordpress y simplemente verificar si el usuario ha iniciado sesión o no.

Para verificar esto, deberá verificar si la cookie nombrada wordpress_logged_in_{some-hash}está presente. De lo contrario, redirija al usuario a la página de inicio de sesión de Wordpress. La {some-hash}parte del nombre de la cookie es solo una serie de letras y dígitos.


fuente
1
Necesito saber qué usuario ha iniciado sesión y también la seguridad es importante.
Esta es una pesadilla de seguridad. Cualquiera puede enviar una solicitud con una cookie estructurada de esta manera. Como no está verificando el hash sino simplemente verificando si hay algo, esto equivale a un formulario de inicio de sesión donde puede ingresar cualquier cosa para el usuario y la contraseña siempre que los campos no estén vacíos.
kraftner