Как проверить логин/пароль без авторизации пользователя

9 авг. 2012 г., 18:39:28
Просмотры: 25.7K
Голосов: 6

Я разрабатываю плагин, который создает API-endpoint для проверки пар логин/пароль.

В настоящее время я использую wp_signon() для проверки работоспособности комбинации логин/пароль. Это хорошо работает, когда учетные данные неверны, так как возвращается объект ошибки. Но когда учетные данные верны, происходит автоматическая авторизация пользователя, поэтому мой endpoint возвращает целую страницу.

В документации даже не упоминается тот факт, что происходит автоматическая авторизация пользователя. Также не похоже, что есть параметр для отключения этой функциональности. Для моих целей достаточно было бы простого булева значения.

ОБНОВЛЕНИЕ: Мне пришлось выбрать один ответ, но было много полезной информации в нескольких других ответах, которую я кратко попробую обобщить...

  1. СУЩЕСТВУЕТ функция, которая делает именно то, что я пытался сделать: wp_authenticate($username, $password) ОДНАКО у нее есть один недостаток. Она автоматически устанавливает куки авторизации, что может создать проблемы в ситуации как у меня. Так что будьте осторожны. Эта функция в настоящее время не документирована в codex.

  2. Лучший выбор для моей задачи - это wp_authenticate_username_password($user, $username, $password), потому что она НЕ устанавливает куки авторизации. Эта функция лучше документирована, но ОЧЕНЬ важная деталь, которой не было в codex - это то, что вы можете передать NULL в качестве первого параметра. Это означает, что вы можете эффективно использовать ее точно так же, как wp_authenticate(), не беспокоясь о проблемах с куками. Прочтите документацию, чтобы не запутаться в ответе. Она возвращает либо объект WP_User, либо WP_Error (не булево значение!).

4
Комментарии

Codex создается пользователями. Просто войдите в систему и измените/отредактируйте/добавьте то, что, по вашему мнению, отсутствует. (Смотрите на это, как на Wikipedia).

kaiser kaiser
9 авг. 2012 г. 19:55:26

Примечание: wp_authenticate на самом деле не устанавливает куки для входа, это происходит в wp_signon. Однако wp_authenticate применяет все подключенные методы аутентификации, поэтому, если вместе с запросом отправлен действительный auth-cookie, он может проверить пользователя независимо от имени пользователя/пароля. Если вы просто хотите проверить имя пользователя и пароль, wp_authenticate_username_password действительно правильный выбор.

Otto Otto
14 авг. 2012 г. 00:52:06

вы когда-нибудь выпускали этот плагин/эндпоинт?

lofidevops lofidevops
25 окт. 2017 г. 01:02:20

@d3vid Это было для личного проекта много лет назад, поэтому код нужно будет обновить для совместимости с текущей версией WP. Но если тебе это интересно, напиши мне на почту.

emersonthis emersonthis
25 окт. 2017 г. 01:35:08
Все ответы на вопрос 4
4
10

В ядерных файлах WordPress есть функция user.php под названием wp_authenticate_username_password, которая, похоже, соответствует тому, что вам нужно.

Если вы хотите избежать передачи объекта $user (вероятно, у вас есть только имя пользователя и пароль), просто передайте null в качестве первого аргумента функции:

$check = wp_authenticate_username_password( NULL, 'some_username', '#thepassw0rd' );

Затем вы можете просто проверить результат с помощью is_wp_error( $check ).

9 авг. 2012 г. 19:15:15
Комментарии

Это работает не так, как кажется. Обычная ошибка (которую и я совершал). Однако я только что обнаружил функцию, которая делает именно то, что нам нужно! Смотрите мой ответ...

emersonthis emersonthis
9 авг. 2012 г. 19:54:24

+1 кажется идеальным решением. Надеюсь, вы не против правки.

kaiser kaiser
9 авг. 2012 г. 19:54:29

@kaiser "Хм". Я никогда не задумывался, что можно передавать NULL в качестве первого параметра. Полезно знать. Также посмотрите wp_authenticate() (см. мой ответ). Я нашел её после недель поисков.

emersonthis emersonthis
9 авг. 2012 г. 20:03:58

Определенно самый эффективный способ.

Adam Adam
9 авг. 2012 г. 20:04:20
1

Используйте,

и

Объяснение

// получаем пользователя по логину через переданное имя пользователя (ввод из формы)
$user = get_user_by('login', $username);

// присваиваем ID пользователя на основе его логина
$user_id = $user->ID;

// получаем данные пользователя, передавая переменную $user_id в get_userdata
// которая возвращает объект пользователя и множество связанных с ним данных для доступа
$user_data = get_userdata($user_id);

// присваиваем имя пользователя и пароль переменным
$user_login = $user_data->user_login;
$user_pass = $user_data->user_pass;

// проверяем имя пользователя/пароль против переданных значений ввода
if ($user_login = $username && $user_pass = $password) {

// делаем что-то...

Примечания

  • $username по умолчанию должен проходить валидацию, иначе объект пользователя не был бы возвращен, если переданный $username не соответствует существующему в базе данных. Таким образом, валидация зависит от переменной $password, которая хранит ввод пароля, предоставленный пользователем.

  • Может существовать более эффективный способ достичь этого, либо сократив существующий код, либо используя другие API-функции.

ОБНОВЛЕНИЕ

Следуя предложению fdsa, вы можете использовать wp_authenticate_username_password следующим образом:

$auth = wp_authenticate_username_password($user, $username, $password);

if (!$auth->user_login = $username && !$auth->user_pass = $password) {

echo 'не аутентифицирован';

} else {

echo 'аутентифицирован';

}

Но еще лучше:

$auth = wp_authenticate_username_password($user, $username, $password);

if (is_wp_error($auth)) {

echo 'не аутентифицирован';

} else {

echo 'аутентифицирован';

}

По праву, заслуга/отмеченный ответ должна принадлежать fdsa за наиболее эффективный метод с использованием (к сожалению) недокументированной функции ядра WP.

http://wpseek.com/wp_authenticate_username_password/

9 авг. 2012 г. 19:12:55
Комментарии

Это отлично. Но get_userdata возвращает хешированный пароль (а не в открытом виде). Есть советы, как обойти это?

emersonthis emersonthis
9 авг. 2012 г. 19:33:47
0

Отказ от ответственности: Этот ответ просто показывает, что происходит за кулисами и не является реальным примером того, как следует делать вещи.


Трассировка вызовов

wp_signon() вызывает wp_set_auth_cookie(), который затем вызывает wp_generate_auth_cookie(). Результат будет использован внутри setcookie() в качестве второго аргумента.

(Неоптимальные) игры с фильтрами

или как обмануть WordPress неправильным способом.

Вы можете перехватить фильтр 'auth_cookie' внутри wp_generate_auth_cookie() и просто установить его значение в null или что-то отличное от SECURE_AUTH_COOKIE или AUTH_COOKIE. Это оставит вам бесполезную куку, которая не сможет выполнить вход.

9 авг. 2012 г. 20:15:30
6

"Та-да": wp_authenticate($username, $password)

Этой функции нет в кодексе, но её можно найти на wpseek.

Она делает именно то, что кажется. Принимает имя пользователя и пароль в открытом виде, а возвращает либо объект WP_User, либо WP_Error... и при этом НЕ входит в систему.

Одно предупреждение! Следующий код ВСЕГДА будет возвращать true (поскольку функция в любом случае возвращает объект):

$auth = ( wp_authenticate($username, $password) ) ? TRUE : FALSE;

Вероятно, вам нужно сделать что-то вроде этого:

$test_creds = wp_authenticate($username, $pass) ;
$class = get_class($test_creds);
$auth = ( $class == 'WP_User' ) ? TRUE : FALSE ;

Надеюсь, это кому-то поможет.

9 авг. 2012 г. 19:59:08
Комментарии

Вы можете использовать instanceof или is_a() для проверки на WP_User. Также можно просто использовать одну из вышеуказанных функций и удалить фильтр на authenticate...

kaiser kaiser
9 авг. 2012 г. 20:03:17

Рекомендую использовать is_wp_error($auth), который вернет TRUE при неудачной аутентификации и FALSE при успешной.

Adam Adam
9 авг. 2012 г. 20:07:56

Еще одно замечание: это не выполнит вход в систему, но cookie останется установленным, так как функция вызывает фильтр `'authenticate`. Если вы выберете это решение, вы должны убедиться, что все callback-функции фильтра удалены. Иначе небо может упасть вам на голову :)

kaiser kaiser
9 авг. 2012 г. 20:20:21

Хорошо знать. У wp_authenticate_username_password( NULL, 'some_username', '#thepassw0rd' ); такая же проблема? Можешь немного подробнее рассказать о "небе, падающем вниз"? Что именно пойдет не так?

emersonthis emersonthis
9 авг. 2012 г. 20:56:20

Примечание: Вместо использования wp_authenticate лучше использовать user_pass_ok($user_login, $user_pass), который в свою очередь использует wp_authenticate как правильную обёрточную функцию, возвращающую true/false. Однако, как сказал @kaiser, куки устанавливаются через фильтр authenticate. Функция wp_authenticate_username_password, судя по всему, не устанавливает куки.

Adam Adam
9 авг. 2012 г. 21:02:33

Согласно документации, wp_authenticate() ДЕЙСТВИТЕЛЬНО авторизует пользователя, если учетные данные верны. Странно, но у меня это не работает.

Gerald Schneider Gerald Schneider
25 июл. 2013 г. 10:16:01
Показать остальные 1 комментариев