有没有一种方法可以使用Wordpress用户,但无需加载整个Wordpress核心?


11

我有一个Wordpress网站和一个Web应用程序,只能由注册(Wordpress)用户使用。

现在,我正在加载wp-blog-header.php以检查用户是否已登录。一切工作正常,但是由于在每个请求(包括AJAX)上我都必须加载Wordpress内核,因此它明显降低了我的应用程序速度(占总数的70%以上)加载时间)。

有没有使用Wordpress用户的简单方法,而无需加载整个Wordpress核心?

更新:我需要知道哪个用户已登录,安全性也很重要。

谢谢!

Answers:


9

如果必须这样做,我将使用自己的cookie来确定登录名,并仅在必要时加载WordPress进行检查。

wordpress_logged_in_ {some-hash} cookie可以用来确定用户,而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发送回给您。您可以先检查一下,然后使用相同的哈希函数和密钥对其进行验证。

只有您可以生成哈希,因为只有您知道密钥。因此,如果他们返回的有效哈希值也与为其WP Cookie发送的哈希值匹配,那么您就知道之前已经通过WP对它们进行了验证,并且可以从该值中正确获取用户名(这是第一个Cookie的一部分)。然后,您不必加载WP。

密钥BTW应该是随机的。不是短密码。不是字典字。只是无意义的胡言乱语。线路噪音,还有很多。示例密钥: 'GHY5hFNqq4Ntdu=3:SUp8#/+_W!- @@^@xslN*L|N+Vn;(1xo8jNyp,au$v9Ki5*'


4

因为我还在用户管理旁边使用了一些Wordpress函数,所以我决定继续加载WP核心,但是我制作了一个自定义文件,该文件仅加载我需要的文件,而不加载插件。新的加载时间令人满意(从完全WP加载时的1.5秒减少到0.3秒)

我已经创建了一个名为“ wp-load-minimum.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 2012年

3

对于Wordpress 4.9:我无法发表评论(新用户)。我用于制作is_user_logged_in()current_user_can()工作的最终灵魂(单个WP安装)如下。我们require('wp-load.php') 第一次 (跳过负载博客- header.php文件WP()) ,并获得ABSPATH恒定的话,手动包括正好所有的东西需要。

手动使用define('SHORTINIT', true)+ require('wp-load.php')+包括:

页面加载量:1.05 sek- 包含的文件:43个文件

比较: 使用require('wp-load.php')

页面加载量:1.35 sek- 包含的文件:419个文件

时间差异(0.3 sek)可能与安装和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 sek。跳过SHORTINIT常数并手动进行处理。


+1可以将第一个调用用作相对调用,如果从绝对URL中借入wp core,事情可能会很混乱。
乔纳斯·隆德曼

2

WordPress本身本身是打开还是关闭。有时,但这只是偶然的原因,而不是设计的结果,您可以解决此问题。但是就您而言,我不确定是否可行。

相反的wp-blog-header.php,你可以尝试只加载WP的功能,包括wp-load.php代替。也许有帮助。


wp-blog-header.php基本上加载,wp-load.php所以没有差异...

2
@Victor:有所不同。它避免了wp();实际耗费的费用。
hakre 2011年

好的,现在我想弄清楚wp()的作用。

我用wp-load.php代替进行了一些测试wp-blog-header.php,一切似乎都可以正常运行,但加载时间相同。

@Victor:您在按F5时正在使用手表还是实际测量?:)无论如何,如果您确实需要框架,请不要使用WordPress。您可以尝试仅加载实际需要的功能。但是,您需要一点一点地寻找它们。仅包括您实际需要的文件,例如用户功能和数据库访问权限。
hakre 2011年

1

您可以尝试直接访问该表。如果您知道密码文件的复杂性,可以让它们通过自己的系统登录,请自己对密码进行复杂性(看看wordpress的工作方式)并自己进行跟踪。如果您希望能够在自己的系统和wordpress之间来回移动而无需重新认证,则可以制作一个可以将当前用户会话传递到系统的wordpress插件。


0

使用WP最快的方法是制作自定义包装,该包装将定义SHORTINIT然后加载核心。这将使核心负载在连接数据库之后,在处理大多数API和扩展(主题和插件)之前立即停止。

从那里,您可以尝试单独获取数据库,或有选择地加载所需的部分核心。

这是一个很麻烦的方法,但是与WP中的情况一样,它也接近更轻的内核负载。


SHORTINIT是一种很好的方法,但是这意味着将不会加载所有用于检查用户和哈希的函数。您可以重新实现,但是如您所说的那样混乱。
奥托

@Otto可能不是重新实现,而是手动加载内核的那些部分。如果插件对用户进行了任何修改,也请手动加载它们。是的,这是相当复杂的方法。但是提高性能的下一个选择是完全放弃WP并直接与数据库一起使用,这更加混乱。
罗斯特(Rarst)2011年


-1

如果您只想允许所有Wordpress用户使用该Web应用程序,则可以使用Wordpress用户管理系统,并只检查该用户是否已登录。

为此,您需要检查是否wordpress_logged_in_{some-hash}存在名为cookie的cookie 。如果不是,请将用户重定向到Wordpress登录页面。{some-hash}Cookie名称的一部分只是一系列字母和数字。


1
我需要知道哪个用户已登录,安全性也很重要。

这是一场安全噩梦。任何人都可以使用结构如下的Cookie发送请求。由于您不是在检查哈希,而是在检查是否有任何等同于登录表单的表单,您可以在其中输入用户名和密码的任何内容,只要字段不为空。
kraftner
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.