I have a WordPress site and a web application that can be used only by the registered (WordPress) users.
Now I’m loading wp-blog-header.php
to check if the user is logged in. Everything is working fine but because on every request (including AJAX) I have to load the WordPress core also, it slows down my application visibly (more than 70% from the total loading time).
Is there any simple way to use the WordPress users but without loading the entire WordPress core?
Update: I need to know which user is logged in and also security is important.
Thank you!
If I had to do this, I’d use my own cookie to determine login and only load WordPress to check when necessary.
The wordpress_logged_in_{some-hash} cookie can be used to determine the user, and WordPress uses it to determine same. You can’t easily reimplement that, but you can use it without loading WordPress on multiple requests.
For example, here’s my cookie hash (completely made up data, but realistic):
The way WordPress knows how that cookie is valid is irrelevant, all you need to know is whether it’s valid one time, then you sign it with a secret.
So, first time, the user isn’t proven yet. You load wp-load.php and WP validates the cookie and logs the user in. You now do whatever you do to prove to yourself that the user has been logged in, then you set your own cookie. The key can be anything custom to you, the value you make into a message digest with a secret key using the hash_hmac function.
You’ll get back gibberish, which you send back to them using setcookie(). On future requests, they’ll send this cookie back to you. You can check that first and validate it using the same hash function and secret key.
Only you can generate the hash because only you know the secret key. So if they send back a valid hash that also matches what they send for their WP cookie, then you know they’ve been validated with WP, through your code, before, and you can get the username right from that value (it’s the first part of the cookie, obviously). Then you don’t have to load WP.
The secret key, BTW, should be long and random. Not a short password. Not a dictionary word. Just large nonsensical gibberish. Line noise, and lots of it. Example key:
'GHY5hFNqq4Ntdu=3:SUp8#/+_W!- @@^@xslN*L|N+Vn;(1xo8jNyp,au$v9Ki5*'
Because I’m also using some WordPress functions beside the users management I decided to continue to load the WP core but I made a custom file that loads only what I need and without loading the plugins. The new loading time is satisfying (it decreased from 1.5s on full WP load to 0.3s)
I’ve made a file called ‘wp-load-minimum.php’ and I call this file instead of ‘wp-blog-header.php’
This is woking for WP 3.3. Here is the content of the file, If you find it useful:
For WordPress 4.9: As I cant comment (new user). The final soultion (single WP install) I use for making
is_user_logged_in()
andcurrent_user_can()
work, is as follow below. Werequire('wp-load.php')
first (to skip wp() in load-blog-header.php), and getABSPATH
constant then, manually includes exactly all the stuff needed.Using
define('SHORTINIT', true)
+require('wp-load.php')
+ manually includes:Pageload: 1.05 sek – included files: 43 files
Comparing: Using ONLY
require('wp-load.php')
:Pageload: 1.35 sek – included files: 419 files
The time difference (0.3 sek) might differ from installs and PHP engines, but while validating many requests on one pageload -things adds up!
Remember to use relative call to WP installed dir. From a WordPress custom plugin dir, inside one subdir level, normal install, a path should be like:
Then:
After this, user validation is accessable. For other task, running on one or two requests, tracking down other needed files might not be not worth 0.3 sek. Skip the
SHORTINIT
constant and manually clutter.WordPress itself only is on or off. Sometimes, but that’s only by chance and not by design, you can work around that. But in your case, I’m not really sure if it’s possible.
Instead of
wp-blog-header.php
you can try to only load the WP functions, includewp-load.php
instead. Maybe that helps.You could try to access the table directly. If you know the salt of the password files you could have them log in via your own system, salt the password yourself (look at how wordpress does it) and keep track of them yourself. If you want the ability to traverse between your own system and wordpress without re-authentication, you could make a plugin to wordpress that passes the current users session to your system.
The fastest you can get with WP is making custom wrapper that will define
SHORTINIT
and then load core. This will make core load stop right after database is connected and before most of APIs and extensions (theme and plugins) are processed.From there you can try to get by database alone or selectively load parts of core you need.
This is quite a messy approach, but it is as close to lighter core load as things get in WP.
Seems there was already discussion about that. So, check updates at: https://core.trac.wordpress.org/ticket/37584
If you just want to allow all WordPress users to use the web app, you can use the WordPress user management system and just check whether the user is logged in or not.
To check this you will need to check whether the cookie named
wordpress_logged_in_{some-hash}
is present. If not, redirect the user to the WordPress login page. The{some-hash}
part of the cookie name is just a series of letters and digits.