1

I have a situation where I need to authenticate users with three values (as opposed to a single USERNAME value. Let's call them VALUE1, VALUE2, VALUE3. They will not be asked for a specific PASSWORD.

I looked into modifying the login routine such that it requests three values, and authenticates the user based on those three values (similar to what's described here). But because Wordpress needs a unique USERNAME field and one of the values entered in the login page will effectively need to be the USERNAME, this won't work, simple because none of the three values are unique in their own right. What's unique is the combination of all three values.

This lead to the idea that the USERNAME stored in WP could be a value derived from concatenating the three values I require (VALUE1, VALUE2, VALUE3). So the USERNAME will be VALUE1VALUE2VALUE3.

I would also use this concatenated value as the PASSWORD, because I don't require the user to enter a separate password if they know the three values I am requesting.

QUESTION 1

My first question is whether or not the above rationale is accurate? Is it true that even if I add additional fields to the login routine, one of those fields will need to correspond to the USERNAME value, and that value will need to be unique?

QUESTION 2

If the above is correct, then my next question is how would I go about creating a login form that requests three fields (plus the password), and concatenates those fields into one value that is authenticated against the USERNAME?

For example

The custom login page will request the following:

VALUE1, VALUE2, VALUE3

It will then concatenate those into VALUE1VALUE2VALUE3 and pass that to the standard WP login routine as the USERNAME and PASSWORD values.


Obviously, I'd want to achieve all this without modifying core files. The site has a child theme, so it can all be done within there.

1
  • Your plan sounds good, the linked post's solution looks like the way to do it (using add_filter( 'authenticate').
    – Picard
    May 13, 2017 at 7:08

2 Answers 2

1

If you create the user by passing the values entered to a function that combines them, then you can call it from another that calls wp_insert_user. Then you can save the username/pass as needed, and use the same function and form when preparing them for WP to check on log-in. All of the code below is intended for demonstration only. Can't stress that enough. Definitely look into nonce and validating registration.

Again, this is ONLY a demo of the idea to point in the general direction.

<form>
    <input type="text" name"value1" />
    <input type="text" name"value2" />
    <input type="text" name"value3" />
</form>

Then we have a function to handle the combining of the entries:

<?php 
function getting_posted_values() {
    if(isset($_POST['value1']) && (isset($_POST['value2']) && (isset($_POST['value3']) {
       $value1 = $_POST['value1'];
       $value2 = $_POST['value2'];
       $value3 = $_POST['value3'];
       $new_value = $value1 . $value2 . $value3;
    }
  return $new_value;
 }

Then a hooked function - (for instance if you used Contact Form 7 to manage the form, you could hook wpcf7_before_send_mail and get access to the post object.) - could call the function below and build the new user:

function build_a_new_user($posted_form) {
    $new_value = getting_posted_values($posted_form);
    $userdata = array(
          'user_login'   => $new_value,
          'user_pass'    => $new_value, //normally: wp_generate_password( 12, false );
          'user_email'   => //note: not sure but may be required?
          'nickname'     => $new_value,
          'display_name' => $new_value,
          'first_name'   => $new_value,
          'last_name'    => $new_value,
          'role'         => 'subscriber'
         );
     wp_insert_user($userdata);

}

wp_insert_user() is documented here.

More on handling custom registration here.

For Logging In

Your form with values 1,2,3 would run getting_post_values again by being called within another function that is hooked to log in somehow. Perhaps the login_form_defaults filter that can edit the args array for the form. The follow is complete speculation as a non-working example.

But the idea is that if you can pass those values to WP's normal process (perhaps via the authenticate filter mentioned in your linked example?) as the user/pass, you can forgo doing the checking yourself.

function log_in_handler($posted_form) {
    $pass_and_username = getting_posted_values($posted_form);
    $args_array = array(
       'username_id' => $pass_and_username, 
       'password' => $pass_and_username);        
}

It's definitely an interesting endeavor. Hope that helps.

1
  • Thank hwl. I appreciate the detailed explanation. In my case, only the login needed to be handled, as the users are all being imported to the DB on masse. I post an answer of what I ended up doing. Again... thanks for the help.
    – omega33
    May 30, 2017 at 0:59
0

Here is what ended up working. In case this is of use to someone wishing to do something similar.

We created a custom template in the child theme.

The final concatenated value is used as the USERNAME and the PASSWORD.

Assuming all other necessary code for a typical custom page template is utilised, I'll just post the beginning of my custom page template file:

<?php
    /**
    Template Name: Custom Login Page
    */
    if ( is_user_logged_in() ) {
        wp_redirect( LOGIN_REDIRECT );  // LOGIN_REDIRECT is set in the config.php file.
    }
    $WP_Error = new WP_Error();

    if(isset($_POST['form-action']) && $_POST['form-action']=='login') {
      $VALUE1 = trim($_POST['log-sname']);
      $VALUE1 = preg_replace("/[^A-Za-z0-9\- ']/", '', $VALUE1);
      $VALUE2 = $_POST['VALUE2'];
      $VALUE3 = $_POST['VALUE3'];
      $usernm = strtoupper(trim($VALUE1)).$VALUE2.$VALUE3;
      $passwd = strtoupper(trim($VALUE1)).$VALUE2.$VALUE3;
      $login_data = array();
      $login_data['user_login'] = $usernm;
      $login_data['user_password'] = $passwd;
      $login_data['remember'] = false;
      $user_verify = wp_signon( $login_data, false ); 
      if ( is_wp_error($user_verify) ) 
      {
        $WP_Error->add('my_error', '<p align="center">We were unable to validate your user credentials. ETC ETC... error message instructions ETC</p>');
      } else {  
        wp_redirect( LOGIN_REDIRECT ); // LOGIN_REDIRECT is set in the config.php file.
        exit();
      }
    }

That's what handles the login. After that comes the header..

    get_header(); ?>

After that is the standard PHP for the loop, etc., plus some code to display the error, if one is generated:

<div id="primary" <?php PARENT_THEME_SPECIFIC_content_class( 'content-area' ); ?> > // use content_class suitable to your theme scenario
    <main id="main" class="site-main" role="main">
      <?php while ( have_posts() ) : the_post(); ?>
        <?php get_template_part( 'template-parts/content', 'page' ); ?>
      <?php endwhile; // End of the loop. ?>
      <?php echo $WP_Error->errors['my_error'][0]; ?>

, and then a form which gathers VALUE1, VALUE2, and VALUE3. The post action is set to "". Here's the form declaration:

Close off with inserting the footer, and whatever else might be wanted.

That's about it.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

Not the answer you're looking for? Browse other questions tagged or ask your own question.