Apakah ada cara untuk menggunakan pengguna Wordpress tetapi tanpa memuat seluruh inti Wordpress?

11

Saya memiliki situs Wordpress dan aplikasi web yang hanya dapat digunakan oleh pengguna terdaftar (Wordpress).

Sekarang saya memuat wp-blog-header.phpuntuk memeriksa apakah pengguna sudah masuk. Semuanya berfungsi dengan baik tetapi karena pada setiap permintaan (termasuk AJAX) saya harus memuat inti Wordpress juga, itu memperlambat aplikasi saya secara nyata (lebih dari 70% dari total memuat waktu).

Apakah ada cara sederhana untuk menggunakan pengguna Wordpress tetapi tanpa memuat seluruh inti Wordpress?

Pembaruan: Saya perlu tahu pengguna mana yang masuk dan keamanan juga penting.

Terima kasih!

Pemenang
sumber

Jawaban:

9

Jika saya harus melakukan ini, saya akan menggunakan cookie saya sendiri untuk menentukan login dan hanya memuat WordPress untuk memeriksa bila perlu.

Cookie wordpress_logged_in_ {some-hash} dapat digunakan untuk menentukan pengguna, dan WordPress menggunakannya untuk menentukan yang sama. Anda tidak dapat dengan mudah mengimplementasikannya, tetapi Anda dapat menggunakannya tanpa memuat WordPress pada banyak permintaan.

Misalnya, inilah hash cookie saya (data yang benar-benar dibuat, tetapi realistis):

key: wordpress_logged_in_1234567890abcdef1234567890abcdef
value: admin|1234567890|abcdef1234567890abcdef1234567890

Cara WordPress mengetahui bagaimana cookie itu valid tidak relevan, yang perlu Anda ketahui adalah apakah cookie itu valid satu kali, kemudian Anda menandatanganinya dengan rahasia.

Jadi, pertama kali, pengguna belum terbukti. Anda memuat wp-load.php dan WP memvalidasi cookie dan login pengguna. Sekarang Anda melakukan apa pun yang Anda lakukan untuk membuktikan kepada diri sendiri bahwa pengguna telah login, maka Anda mengatur cookie Anda sendiri. Kuncinya bisa berupa apa saja yang kustom untuk Anda, nilai yang Anda buat menjadi intisari pesan dengan kunci rahasia menggunakan fungsi 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' );

Anda akan mendapatkan kembali omong kosong, yang Anda kirim kembali kepada mereka menggunakan setcookie (). Atas permintaan di masa mendatang, mereka akan mengirimkan cookie ini kepada Anda. Anda dapat memeriksa itu terlebih dahulu dan memvalidasinya menggunakan fungsi hash dan kunci rahasia yang sama.

Hanya Anda yang dapat menghasilkan hash karena hanya Anda yang mengetahui kunci rahasia. Jadi jika mereka mengirim kembali hash yang valid yang juga cocok dengan apa yang mereka kirim untuk cookie WP mereka, maka Anda tahu mereka telah divalidasi dengan WP, melalui kode Anda, sebelumnya, dan Anda bisa mendapatkan nama pengguna langsung dari nilai itu (itu yang pertama bagian dari cookie, jelas). Maka Anda tidak perlu memuat WP.

Kunci rahasia, BTW, harus panjang dan acak . Bukan kata sandi pendek. Bukan kata kamus. Omong kosong hanya besar. Garis kebisingan, dan banyak. Contoh kunci: 'GHY5hFNqq4Ntdu=3:SUp8#/+_W!- @@^@xslN*L|N+Vn;(1xo8jNyp,au$v9Ki5*'

Otto
sumber
4

Karena saya juga menggunakan beberapa fungsi Wordpress di samping manajemen pengguna, saya memutuskan untuk terus memuat inti WP tetapi saya membuat file khusus yang hanya memuat apa yang saya butuhkan dan tanpa memuat plugin. Waktu pemuatan baru memuaskan (menurun dari 1,5 detik pada WP penuh menjadi 0,3 detik)

Saya telah membuat file bernama 'wp-load-minimum.php' dan saya memanggil file ini alih-alih 'wp-blog-header.php'

Ini terbangun untuk WP 3.3. Berikut adalah isi file tersebut, Jika Anda merasa berguna:

<?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' );
Pemenang
sumber
1
Ini ide yang bagus. Satu saran: Anda mungkin dapat membuang pemuatan plugin dan mengatur kueri (tentu saja tergantung pada kasus penggunaan Anda).
chrisguitarguy
3

Untuk Wordpress 4.9: As I cant comment (pengguna baru). Soultion terakhir (instalasi WP tunggal) yang saya gunakan untuk membuat is_user_logged_in()dan current_user_can()bekerja, adalah sebagai berikut di bawah ini. Kami require('wp-load.php') pertama-tama (untuk melewatkan wp () di load-blog-header.php) , dan mendapatkan ABSPATHkonstanta kemudian, secara manual menyertakan persis semua hal yang dibutuhkan.

Menggunakan define('SHORTINIT', true)+ require('wp-load.php')+ secara manual meliputi:

Pageload: 1,05 sek - file yang disertakan: 43 file

Membandingkan: HANYA MENGGUNAKAN require('wp-load.php'):

Pageload: 1,35 sek - file yang disertakan: 419 file

Perbedaan waktu (0,3 sek) mungkin berbeda dari pemasangan dan mesin PHP, tetapi sementara memvalidasi banyak permintaan pada satu pageload - hal-hal bertambah!

Ingatlah untuk menggunakan panggilan relatif ke direktori yang diinstal WP. Dari dir plugin kustom Wordpress, di dalam satu level subdir, instal normal, path harus seperti:

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

Kemudian:

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

Setelah ini, validasi pengguna dapat diakses. Untuk tugas lain, tidak ada pada satu atau dua permintaan , melacak file lain yang diperlukan mungkin tidak bernilai 0,3 sek. Lewati SHORTINITkekacauan konstan dan manual.

Anna Ericson
sumber
+1 untuk menggunakan panggilan pertama sebagai relatif, Hal-hal bisa sangat berantakan jika meminjamkan wp core dari url absolut.
Jonas Lundman
2

Wordpress sendiri hanya hidup atau mati. Kadang-kadang, tapi itu hanya karena kebetulan dan bukan karena desain, Anda bisa mengatasinya. Tetapi dalam kasus Anda, saya tidak begitu yakin apakah itu mungkin.

Dari pada wp-blog-header.php Anda dapat mencoba hanya memuat fungsi WP, sertakan wp-load.phpsaja. Mungkin itu membantu.

hakre
sumber
wp-blog-header.phppada dasarnya memuat wp-load.phpsehingga tidak ada perbedaan ...
2
@ Viktor: Ada perbedaan. Itu menghemat api wp();yang sebenarnya cukup mahal.
hakre
OK, sekarang saya mencoba mencari tahu apa sebenarnya wp ().
Saya telah membuat beberapa tes dengan wp-load.phpalih - alih wp-blog-header.php, semuanya tampaknya berfungsi dengan baik tetapi waktu pemuatannya sama.
@ Viktor: Apakah Anda menggunakan arloji sambil menekan F5 atau bagaimana mengukurnya? :) Pokoknya, jangan gunakan WordPress jika Anda benar-benar membutuhkan kerangka kerja. Anda dapat mencoba hanya memuat fungsi yang sebenarnya Anda butuhkan saja. Tetapi Anda perlu mencarinya sedikit demi sedikit. Cukup sertakan file yang sebenarnya Anda butuhkan, seperti untuk fungsi pengguna dan akses database mungkin.
hakre
1

Anda dapat mencoba mengakses tabel secara langsung. Jika Anda tahu garam dari file kata sandi Anda bisa membuatnya masuk melalui sistem Anda sendiri, beri garam kata sandi sendiri (lihat bagaimana wordpress melakukannya) dan catat sendiri. Jika Anda ingin kemampuan untuk melintasi antara sistem Anda sendiri dan wordpress tanpa otentikasi ulang, Anda bisa membuat plugin untuk wordpress yang melewati sesi pengguna saat ini ke sistem Anda.


sumber
0

Yang tercepat yang Anda dapatkan dengan WP adalah membuat pembungkus khusus yang akan ditentukan SHORTINIT dan kemudian memuat inti. Ini akan membuat core load berhenti tepat setelah basis data terhubung dan sebelum sebagian besar API dan ekstensi (tema dan plugin) diproses.

Dari sana Anda dapat mencoba mendapatkan dengan basis data sendiri atau secara selektif memuat bagian inti yang Anda butuhkan.

Ini adalah pendekatan yang cukup berantakan, tetapi dekat dengan beban inti yang lebih ringan seperti yang ada di WP.

Jarang
sumber
SHORTINIT adalah pendekatan yang baik, tetapi ini berarti bahwa semua fungsi untuk memeriksa pengguna dan hash dan semacamnya tidak akan dimuat. Anda bisa menerapkannya, tapi berantakan, seperti yang Anda katakan.
Otto
@ Otto Mungkin tidak mengimplementasikan ulang, tetapi memuat bagian-bagian inti dengan tangan. Dan jika ada modifikasi terhadap pengguna sedang dilakukan oleh plugins memuatnya dengan tangan juga. Ya, ini pendekatan yang cukup terlibat. Tetapi alternatif berikutnya untuk kinerja yang lebih baik adalah membuang WP sepenuhnya dan bekerja dengan database secara langsung, yang bahkan lebih berantakan.
Rarst
-1

Jika Anda hanya ingin mengizinkan semua pengguna Wordpress untuk menggunakan aplikasi web, Anda dapat menggunakan sistem manajemen pengguna Wordpress dan hanya memeriksa apakah pengguna tersebut login atau tidak.

Untuk memeriksa ini, Anda perlu memeriksa apakah ada cookie yang bernama wordpress_logged_in_{some-hash}. Jika tidak, arahkan pengguna ke halaman login Wordpress. Bagian {some-hash}dari nama cookie hanyalah serangkaian huruf dan angka.


sumber
1
Saya perlu tahu pengguna mana yang masuk dan keamanan juga penting.
Ini adalah mimpi buruk keamanan. Siapa pun dapat mengirim permintaan dengan cookie yang terstruktur seperti ini. Karena Anda tidak memeriksa hash tetapi hanya memeriksa apakah ada sesuatu yang setara dengan formulir login di mana Anda dapat memasukkan apa pun untuk pengguna dan kata sandi selama isian tidak kosong.
kraftner