Here’s the solution I came up with that relies on the info already present in the database.
Background
Each password-protected post stores the password in plaintext in the wp_posts
table (in the post_password
column). We can use that to query the db for any posts that have that password assigned and get the post info based on that. From there, we can redirect to the password-protected post.
Assumptions/constraints
The OP stated that a custom login form would be used for clients to enter their special password. I’m assuming that form is created and can use a GET request to send the password since it’s already plaintext.
The OP also stated each password protecting the post/page would be unique. I’m assuming that unique password is generated separately from this answer.
How it works
A query string of client_key
is sent (either through the GET of the form, or through a link) and checked using get_query_var()
. If it’s present, check the wp_posts
table for the first post that has a password set that equals the client_key
and return the row as an object.
Sanity check: if object has been created, create a couple of variables to use in our JavaScript function.
Echo a script
element into the DOM that will run a POST function to wp-login.php
. This mimics the form posting that would normally happen when a password-protected page is visited for the first time. There, the client would be prompted for the password to view the post content, and once it was given a cookie is created to allow future access to the content.
This function does the same form submission behind the scenes, the redirects to the appropriate post (based on GUID).
Finally, only run the function on the front-end of the site, when wp_head
is fired (when jQuery is [usually] loaded).
The code
<?php
/**
* Add our custom query string to the global query_vars.
*
* @param array $vars The global vars used throughout WP.
*
* @return array
*/
function wpse134962_add_query_vars_filter( $vars ) {
$vars[] = 'client_key';
return $vars;
}
add_filter( 'query_vars', 'wpse134962_add_query_vars_filter' );
/**
* Redirect to a password-protected page based on the query string.
*
* If client_key is passed in the query string, check the database for a post that
* has a password assigned that equals the client_key. If one is found, submit the
* login form to create the cookie that allows entry, then redirect to the post.
*/
function wpse134962_password_redirect() {
$client_key = get_query_var( 'client_key' ) ? get_query_var( 'client_key' ) : '';
if ( ! empty( $client_key ) ) {
/** @var wpdb $wpdb */
global $wpdb;
$query = $wpdb->prepare( "SELECT * FROM $wpdb->posts WHERE post_password = %s", $client_key );
$password_posts = $wpdb->get_row( $query );
if ( isset( $password_posts ) ) {
$post_id = $password_posts->ID;
$login_url = site_url( 'wp-login.php' );
echo <<<HTML
<script>
jQuery(function() {
var postURL = "$login_url?action=postpass",
postData = {
post_password: "$client_key"
},
postRedirect = function() {
document.location = "{$password_posts->guid}";
};
jQuery.post( postURL, postData, postRedirect() );
})();
</script>
HTML;
}
}
}
if ( ! is_admin() ) {
/** Only fire on the front end of the site. */
add_action( 'wp_head', 'wpse134962_password_redirect' );
}