admin管理员组

文章数量:1305195

On my site i have one form for client to submit their WordPress site details. On that form containing these fields WordPress admin url, username, and password. I want to check their login details are valid before submitting the form. How i do that?

If there any way to do by using WordPress REST API?

If anyone know please help me Thanks !

On my site i have one form for client to submit their WordPress site details. On that form containing these fields WordPress admin url, username, and password. I want to check their login details are valid before submitting the form. How i do that?

If there any way to do by using WordPress REST API?

If anyone know please help me Thanks !

Share Improve this question edited Apr 23, 2018 at 9:25 bueltge 17.1k7 gold badges62 silver badges97 bronze badges asked Apr 17, 2018 at 12:06 developermedeveloperme 1415 silver badges18 bronze badges 7
  • without customisation, the REST API doesn't permit to test the password. then if you want to test it, you can send it at wp-login.php. – mmm Commented Apr 17, 2018 at 12:44
  • @mmm how i do that? Do you have any idea about this? – developerme Commented Apr 17, 2018 at 12:46
  • you can try with wp_remote_post – mmm Commented Apr 17, 2018 at 13:19
  • According to stackoverflow/questions/13679001/… you can test a remote login – Clemens Tolboom Commented Apr 21, 2018 at 6:41
  • 1 This sounds like you're trying to do something you shouldn't. You could easily build a brute-force attack using your application. What is the usage scenario for your request? – Ciprian Commented Apr 25, 2018 at 14:02
 |  Show 2 more comments

3 Answers 3

Reset to default 3 +25

Getting user names and passwords is a horrible idea I hope no user will actually agree to, but beyond that your idea to do it from JS is going to fail due to CORS, which means you will have to do it in AJAX to your server, and let your server try to login, which in turn will most likely flag it as a brute force attacker in no time, and all the major security players will just automatically block the requests.

You need to redesign you software to not need user name and password, probably use something like oauth2 instead. If oauth2 is not applicable for your situation.... well, tough luck.

First off: there are many reasons why the following code could fail. There is no way to have a system that works everywhere. This is due to various security plugins introducing many different concepts.

Having said that, this code worked for a plain installation as well as one with Wordfence (with not super strict settings) enabled.


wp_remote_post() is the key function in this function. It allows you to send POST requests to remote hosts - which is exactly what you want if you want to check a login.

function WPSE_test_remote_login($url, $username, $password) {
    // remove trailing slash if it exists
    $base = rtrim($url, '/');

    // login url
    $url = $base . '/wp-login.php';

    $args = [
        // the inputs that get POSTed
        'body' => [
            'log' => $username,
            'pwd' => $password,
            'wp-submit' => 'Submit',
            'redirect_to' => $base . '/wp-admin/',
            'testcookie' => 1,
        ],
    ];

    // make the actual request
    $response = wp_remote_post($url, $args);

    // only one cookie? then failed login
    if ( ! is_array($response['headers']['set-cookie'])) {
        return false;
    }

    // if a cookie that contains wordpress_logged_in is set
    // the login was successful
    foreach ($response['headers']['set-cookie'] as $cookie) {
        if (stripos($cookie, 'wordpress_logged_in') !== FALSE) {
            return true;
        }
    }

    return false;
}

I tried this in my local environment, you can get the necessary fields that are usually sent if you access the wp-login.php in your browser.

Then I checked the $result and compared the difference between correct and wrong password. For a failed login, $response['headers']['set-cookie'] looked like this

string(45) "wordpress_test_cookie=WP+Cookie+check; path=/"

or this

array(3) {
  [0]=>
  string(128) "__cfduid=df131...; expires=Sun, 21-Apr-19 12:35:00 GMT; path=/; domain=.example; HttpOnly"
  [1]=>
  string(100) "wfvt_144...=5ad...; expires=Sat, 21-Apr-2018 13:05:00 GMT; Max-Age=1800; path=/; HttpOnly"
  [2]=>
  string(74) "wordpress_test_cookie=WP+Cookie+check; path=/; domain=.example; secure"
}

However, a successful login returned these cookies

array(4) {
  [0]=>
  string(45) "wordpress_test_cookie=WP+Cookie+check; path=/"
  [1]=>
  string(209) "wordpress_852...=test%7C15...; path=/wp-content/plugins; HttpOnly"
  [2]=>
  string(199) "wordpress_852...=test%7C15...; path=/wp-admin; HttpOnly"
  [3]=>
  string(201) "wordpress_logged_in_852...=test%7C15...; path=/; HttpOnly"
}

We see that wordpress_test_cookie will always get set. However, wordpress_logged_in_852... was only set for successful logins. So we can determine that if this exists, the credentials are correct.

There is no way to achieve this without any custom API routes. But of course, you can register such route (or use AJAX instead), if you can edit theme or install plugins on that site.

So, let's do this with REST API...

function my_register_api_hooks() {
    register_rest_route(
        'my_namespace', '/check-login/',
        array(
            'methods'  => 'POST',
            'callback' => 'my_api_check_login_callback',
        )
    );
}
add_action( 'rest_api_init', 'my_register_api_hooks' );
    
function my_api_check_login_callback($request){
    $user = wp_authenticate_username_password(null, $request['username'], $request['password']);

    if ( is_wp_error($user) ) {
        return array('error' => $user, 'user' => false);
    }

    return array('error' => false, 'user' => $user->ID);
}

When you'll send a POST request to

http://example/wp-json/my_namespace/check-login/

containing username and password, you'll get JSON like this:

{
  "error": false,
  "user": 1
}

where 1 is the ID of user found for given credentials, or

{
  "error": "...", <- this will contain error messages
  "user": false
}

You have to be aware that this code only checks if user credentials are correct. It will not log user in.

And what if you have no control over site you want to check?

Then there is no way to register your own routes and there's no way to use REST to check user credentials. But... You can use XMLRPC...

One way will be using this library: WordPress XML-RPC PHP Client. It will do the job for you almost all the way or you can use native WP_HTTP_IXR_Client class.

You can use wp.getUsersBlogs method for checking if given credentials are correct.

本文标签: plugin developmentHow to check WordPress website username and password is correct