Gibt es eine Möglichkeit, die Wordpress-Benutzer zu verwenden, ohne jedoch den gesamten Wordpress-Kern zu laden?


11

Ich habe eine Wordpress-Site und eine Webanwendung, die nur von registrierten (Wordpress) Benutzern verwendet werden kann.

Jetzt lade ich wp-blog-header.php, um zu überprüfen, ob der Benutzer angemeldet ist. Alles funktioniert einwandfrei, aber da ich bei jeder Anfrage (einschließlich AJAX) auch den Wordpress-Kern laden muss, verlangsamt dies meine Anwendung sichtbar (mehr als 70% der Gesamtzahl) Ladezeit).

Gibt es eine einfache Möglichkeit, die Wordpress-Benutzer zu verwenden, ohne jedoch den gesamten Wordpress-Kern zu laden?

Update: Ich muss wissen, welcher Benutzer angemeldet ist und auch die Sicherheit ist wichtig.

Vielen Dank!

Antworten:


9

Wenn ich dies tun müsste, würde ich mein eigenes Cookie verwenden, um die Anmeldung zu bestimmen, und WordPress nur laden, um es bei Bedarf zu überprüfen.

Das Cookie wordpress_logged_in_ {some-hash} kann verwendet werden, um den Benutzer zu bestimmen, und WordPress verwendet es, um denselben zu bestimmen. Sie können dies nicht einfach erneut implementieren, aber Sie können es verwenden, ohne WordPress bei mehreren Anforderungen zu laden.

Hier ist zum Beispiel mein Cookie-Hash (vollständig erfundene Daten, aber realistisch):

key: wordpress_logged_in_1234567890abcdef1234567890abcdef
value: admin|1234567890|abcdef1234567890abcdef1234567890

Die Art und Weise, wie WordPress weiß, wie dieses Cookie gültig ist, spielt keine Rolle. Sie müssen lediglich wissen, ob es einmal gültig ist, und dann unterschreiben Sie es mit einem Geheimnis.

Zum ersten Mal ist der Benutzer also noch nicht bewiesen. Sie laden wp-load.php und WP validiert das Cookie und meldet den Benutzer an. Sie tun nun alles, um sich selbst zu beweisen, dass der Benutzer angemeldet ist, und setzen dann Ihr eigenes Cookie. Der Schlüssel kann alles sein, was für Sie benutzerdefiniert ist, der Wert, den Sie mit einem geheimen Schlüssel mithilfe der Funktion hash_hmac in einen Message Digest umwandeln.

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

Sie erhalten Kauderwelsch zurück, das Sie mit setcookie () an sie zurücksenden. Bei zukünftigen Anfragen senden sie diesen Cookie an Sie zurück. Sie können dies zuerst überprüfen und mit derselben Hash-Funktion und demselben geheimen Schlüssel validieren.

Nur Sie können den Hash generieren, da nur Sie den geheimen Schlüssel kennen. Wenn sie also einen gültigen Hash zurücksenden, der auch mit dem übereinstimmt, was sie für ihr WP-Cookie senden, wissen Sie, dass sie zuvor über Ihren Code mit WP validiert wurden, und Sie können den Benutzernamen direkt von diesem Wert abrufen (es ist der erste offensichtlich ein Teil des Cookies). Dann müssen Sie WP nicht laden.

Der geheime Schlüssel BTW sollte lang und zufällig sein . Kein kurzes Passwort. Kein Wörterbuchwort. Nur großer unsinniger Kauderwelsch. Leitungsrauschen und viel davon. Beispielschlüssel: 'GHY5hFNqq4Ntdu=3:SUp8#/+_W!- @@^@xslN*L|N+Vn;(1xo8jNyp,au$v9Ki5*'


4

Da ich neben der Benutzerverwaltung auch einige Wordpress-Funktionen verwende, habe ich beschlossen, den WP-Kern weiterhin zu laden, aber ich habe eine benutzerdefinierte Datei erstellt, die nur das lädt, was ich brauche, und ohne die Plugins zu laden. Die neue Ladezeit ist zufriedenstellend (sie verringerte sich von 1,5 s bei voller WP-Last auf 0,3 s).

Ich habe eine Datei mit dem Namen 'wp-load-minimum.php' erstellt und rufe diese Datei anstelle von 'wp-blog-header.php' auf.

Dies weckt WP 3.3. Hier ist der Inhalt der Datei, wenn Sie es nützlich finden:

<?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
Das ist eine gute Idee. Ein Vorschlag: Sie können wahrscheinlich das Laden von Plugins und das Einrichten von Abfragen aufgeben (natürlich abhängig von Ihrem Anwendungsfall).
Chrisguitarguy

3

Für Wordpress 4.9: Da ich keinen Kommentar abgeben kann (neuer Benutzer). Die letzte Lösung (einzelne WP-Installation), die ich zum Erstellen is_user_logged_in()und current_user_can()Arbeiten verwende, ist wie folgt. Wir überspringen require('wp-load.php') zuerst (um wp () in load-blog-header.php zu überspringen) und ABSPATHwerden dann konstant und enthalten manuell genau alle benötigten Dinge .

Die manuelle Verwendung von define('SHORTINIT', true)+ require('wp-load.php')+ umfasst:

Pageload: 1.05 sek - enthaltene Dateien: 43 Dateien

Vergleichen: NUR mit require('wp-load.php') :

Pageload: 1.35 sek - enthaltene Dateien: 419 Dateien

Der Zeitunterschied (0,3 Sek.) Kann sich von Installationen und PHP-Engines unterscheiden, aber während die Validierung vieler Anfragen auf einer Seite - Dinge summieren sich!

Denken Sie daran, den relativen Aufruf des installierten WP-Verzeichnisses zu verwenden. Aus einem benutzerdefinierten Wordpress-Plugin-Verzeichnis sollte innerhalb einer Unterverzeichnisebene bei normaler Installation ein Pfad wie folgt aussehen:

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

Dann:

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

Danach kann auf die Benutzerüberprüfung zugegriffen werden. Bei anderen Aufgaben, bei denen ein oder zwei Anforderungen nicht erfüllt werden , ist das Aufspüren anderer benötigter Dateien möglicherweise nicht 0,3 Sek. Wert. Überspringen Sie die SHORTINITKonstante und manuelle Unordnung.


+1, um den ersten Aufruf als relativ zu verwenden. Dinge könnten wirklich chaotisch sein, wenn man wp core von absoluten URLs leiht.
Jonas Lundman

2

Wordpress selbst ist nur ein- oder ausgeschaltet. Manchmal, aber das ist nur zufällig und nicht beabsichtigt, können Sie das umgehen. Aber in Ihrem Fall bin ich mir nicht sicher, ob es möglich ist.

Anstatt zu wp-blog-header.phpversuchen, nur die WP-Funktionen zu laden, schließen Sie wp-load.phpstattdessen ein. Vielleicht hilft das.


wp-blog-header.phpGrundsätzlich wp-load.phpwird geladen, so dass es keinen Unterschied gibt ...

2
@ Victor: Es gibt einen Unterschied. Es erspart das Feuer, wp();was eigentlich ziemlich teuer ist.
hakre

OK, jetzt versuche ich herauszufinden, was genau wp () tut.

Ich habe einige Tests mit wp-load.phpstatt gemacht wp-blog-header.php, alles scheint gut zu funktionieren, aber die Ladezeit ist die gleiche.

@ Victor: Verwenden Sie Ihre Uhr, während Sie F5 drücken, oder wie messen Sie tatsächlich? :) Verwenden Sie auf keinen Fall WordPress, wenn Sie tatsächlich ein Framework benötigen. Sie können versuchen, stattdessen nur die Funktionen zu laden, die Sie tatsächlich benötigen. Aber Sie müssen sie Stück für Stück suchen. Fügen Sie einfach die Dateien hinzu, die Sie tatsächlich benötigen, z. B. für Benutzerfunktionen und den Datenbankzugriff.
hakre

1

Sie können versuchen, direkt auf die Tabelle zuzugreifen. Wenn Sie das Salz der Passwortdateien kennen, können Sie sie über Ihr eigenes System anmelden, salzen Sie das Passwort selbst (sehen Sie, wie WordPress es macht) und verfolgen Sie sie selbst. Wenn Sie die Möglichkeit haben möchten, ohne erneute Authentifizierung zwischen Ihrem eigenen System und WordPress zu wechseln, können Sie ein Plugin für WordPress erstellen, das die aktuelle Benutzersitzung an Ihr System weiterleitet.


0

Das schnellste, was Sie mit WP erreichen können, ist die Erstellung eines benutzerdefinierten Wrappers, der den SHORTINITKern definiert und dann lädt. Dadurch wird die Kernlast direkt nach dem Verbinden der Datenbank und vor der Verarbeitung der meisten APIs und Erweiterungen (Design und Plugins) gestoppt.

Von dort aus können Sie versuchen, nur über die Datenbank zu gelangen oder Teile des Kerns, die Sie benötigen, selektiv zu laden.

Dies ist ein ziemlich chaotischer Ansatz, aber er kommt einer leichteren Kernlast so nahe, wie es in WP nur geht.


SHORTINIT ist ein guter Ansatz, aber dies bedeutet, dass alle Funktionen zum Überprüfen von Benutzern und Hashes und dergleichen nicht geladen werden. Sie könnten das wieder umsetzen, aber chaotisch, wie Sie sagten.
Otto

@Otto Wahrscheinlich nicht neu implementieren, sondern diese Teile des Kerns von Hand laden. Und wenn es Änderungen an den Benutzern gibt, die durch Plugins vorgenommen werden, laden Sie diese ebenfalls von Hand. Ja, das ist ein ziemlich komplizierter Ansatz. Die nächste Alternative für eine bessere Leistung besteht darin, WP vollständig aufzugeben und direkt mit der Datenbank zu arbeiten, was noch chaotischer ist.
Erster


-1

Wenn Sie nur allen Wordpress-Benutzern die Verwendung der Web-App erlauben möchten, können Sie das Wordpress-Benutzerverwaltungssystem verwenden und nur prüfen, ob der Benutzer angemeldet ist oder nicht.

Um dies zu überprüfen, müssen Sie überprüfen, ob das genannte Cookie wordpress_logged_in_{some-hash}vorhanden ist. Wenn nicht, leiten Sie den Benutzer zur Wordpress-Anmeldeseite weiter. Der {some-hash}Teil des Cookie-Namens besteht nur aus einer Reihe von Buchstaben und Ziffern.


1
Ich muss wissen, welcher Benutzer angemeldet ist und auch die Sicherheit ist wichtig.

Dies ist ein Sicherheitsalptraum. Jeder kann eine Anfrage mit einem Cookie senden, das so aufgebaut ist. Da Sie nicht den Hash überprüfen, sondern nur prüfen, ob etwas vorhanden ist, entspricht dies einem Anmeldeformular, in das Sie alles für Benutzer und Kennwort eingeben können, solange die Felder nicht leer sind.
Kraftner
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.