Take the 2-minute tour ×
WordPress Development Stack Exchange is a question and answer site for WordPress developers and administrators. It's 100% free, no registration required.

I tried doing something like this:

$user = $wpdb->get_row('
    SELECT * 
    FROM ' . $wpdb->users . ' 
    WHERE user_pass = "' . wp_hash_password('password') . '"'
);

But the wp_hash_password function generates a different string from the one in the database, is it possible?

What I'd like to do is have a custom form in my template that just asks for a password (think of it like the username/pwd screen to the WP admin area without the username) so I'd hash whatever the user inputs, compare it with my DB and if it matches take that user and log him in.

share|improve this question
1  
Ignoring the objection for doing it at all, why do you think the password in the DB was generated with wp_hash_password? what value do you expect to be there and what value do you get? –  Mark Kaplun Jan 22 '13 at 13:59
    
Very very bad man –  userabuser Jan 22 '13 at 14:33
    
@MarkKaplun I though that's they function WP used when creating a new user but it looks like they do something different. If I hash a string with wp_hash_password it generates a random string every time it runs –  javiervd Jan 22 '13 at 15:36
1  
I agree with everyone else that says this is a terrible idea. That said, look at wp_check_password documentation for how to match passwords. –  Dan Jan 22 '13 at 16:08
    
I know it's not a very good idea but it's a request from a client and I just wanted to know if it was possible. I checked wp_check_password and I think it might work, I can loop through the users table and check every hash against the string the user inputs and if something matches then return that user's ID. I'll give it a go. –  javiervd Jan 22 '13 at 16:27

3 Answers 3

Password is not unique all the time.

According to worst password statistics, password is the most used Password of all time.

I'm pretty sure some of your users too use that password.

So multiple rows will contain the same hash. Hence its not possible.

By the way, this is a weird question.

enter image description here

share|improve this answer
3  
And even different passwords can result in identical hashes. Hashes are by their nature not collision safe. –  toscho Jan 22 '13 at 6:13
    
That was just an example, I just want to know if it's possible to login a user by just asking the password, there should be a way to hash the text string to be the same as in the DB (kind of how the wp_signon function works). I guess hashes can be the same even if the password is different but really how likely is this scenario considering passwords have ~30 characters? –  javiervd Jan 22 '13 at 6:14
    
You enforce 30 character passwords? Are you confusing the hash with the password? The hash might have ~30 characters but the pass could still be "hi". –  s_ha_dum Jan 22 '13 at 6:23
    
Giri, can you provide the link for the statistics? –  brasofilo Jan 22 '13 at 9:32
    
@brasofilo Updated answer with statistics image –  Giri Jan 22 '13 at 12:23

Per the comments I'm going to answer a paraphrased question - "How to make a login form which shows only the password field in most cases".

The answer is to store the user name in a very long term cookie (a year?) every time the user logins.

function wpse82578_set_user_cookie($logged_in_cookie, $expire, $expiration, $user_id, $state) {
  if ($state == 'logged_in') { // user has logged in - store his name in a 'username' cookie
    $user = get_user_by( 'id', $user_id );
    setcookie('username', $user->user_login, time() + 365*24*60*60, COOKIEPATH, COOKIE_DOMAIN);
  }
}
add_action('set_logged_in_cookie', 10,5);

Now in you PHP code you can check if the cookie is set and show or hide the user name field in your form.

function wpse82578_echo_login_form() {
   ...
   if (isset($_COOKIE['username'])) { // already know the user name, no point in asking for it again so just put it as hidden field
     <input type="hidden" name="log" value="<?php esc_attr($_COOKIE['username'])?> />
   else { // show the field+label, ripped from wp_login_form
        <p class="login-username">
            <label for="' . esc_attr( $args['id_username'] ) . '">' . esc_html( $args['label_username'] ) . '</label>
            <input type="text" name="log" id="' . esc_attr( $args['id_username'] ) . '" class="input" value="' . esc_attr( $args['value_username'] ) . '" size="20" tabindex="10" />
        </p>
    }
}

No warranties for this code, but I think it is the best approximation to what you want without sacrificing security and messing with the WordPress user system.

share|improve this answer
up vote 0 down vote accepted

Here's what I ended up doing in case someone else need a similar functionality:

// Simple text password
$client_password = $_POST['client_pwd'];

$users = get_users();

// Iterate over all users and see if the password matches
foreach ($users as $user) {
    // If it matches log the user in
    if (wp_check_password($client_password, $user->user_pass)) {
        $user = wp_signon(
            array(
                'user_login'    => $user->user_login,
                'user_password' => $client_password
            )
        );

        if (!is_wp_error($user)) {
            // Redirect or do something else
        }
    }
}
share|improve this answer

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

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