wp_authenticate_application_password()
云策文档标注
概述
wp_authenticate_application_password() 是 WordPress 中用于通过应用密码验证用户的函数。它主要用于 REST API 或 XML-RPC 请求,验证用户名和密码是否匹配有效的应用密码,并返回 WP_User 对象或错误。
关键要点
- 函数参数包括 $input_user(WP_User 或 WP_Error 对象)、$username(用户名)和 $password(密码),返回 WP_User、WP_Error 或 null。
- 默认仅适用于 API 请求(REST_REQUEST 或 XMLRPC_REQUEST),可通过 application_password_is_api_request 过滤器覆盖。
- 验证过程包括检查用户是否存在、应用密码是否可用、密码匹配性,并触发相关钩子如 wp_authenticate_application_password_errors。
- 成功验证后记录使用并触发 application_password_did_authenticate 动作。
代码示例
$user = wp_authenticate_application_password(null, $_SERVER['PHP_AUTH_USER'], $_SERVER['PHP_AUTH_PW']);
if ($user instanceof WP_User) {
// Do authenticated stuff
}注意事项
- 应用密码需为字母数字,函数会去除非字母数字字符进行验证。
- 验证失败时返回 WP_Error 并触发 application_password_failed_authentication 动作。
- 可通过过滤器临时允许非 API 请求使用应用密码验证。
原文内容
Authenticates the user using an application password.
Parameters
Source
function wp_authenticate_application_password(
$input_user,
$username,
#[SensitiveParameter]
$password
) {
if ( $input_user instanceof WP_User ) {
return $input_user;
}
if ( ! WP_Application_Passwords::is_in_use() ) {
return $input_user;
}
// The 'REST_REQUEST' check here may happen too early for the constant to be available.
$is_api_request = ( ( defined( 'XMLRPC_REQUEST' ) && XMLRPC_REQUEST ) || ( defined( 'REST_REQUEST' ) && REST_REQUEST ) );
/**
* Filters whether this is an API request that Application Passwords can be used on.
*
* By default, Application Passwords is available for the REST API and XML-RPC.
*
* @since 5.6.0
*
* @param bool $is_api_request If this is an acceptable API request.
*/
$is_api_request = apply_filters( 'application_password_is_api_request', $is_api_request );
if ( ! $is_api_request ) {
return $input_user;
}
$error = null;
$user = get_user_by( 'login', $username );
if ( ! $user && is_email( $username ) ) {
$user = get_user_by( 'email', $username );
}
// If the login name is invalid, short circuit.
if ( ! $user ) {
if ( is_email( $username ) ) {
$error = new WP_Error(
'invalid_email',
__( '<strong>Error:</strong> Unknown email address. Check again or try your username.' )
);
} else {
$error = new WP_Error(
'invalid_username',
__( '<strong>Error:</strong> Unknown username. Check again or try your email address.' )
);
}
} elseif ( ! wp_is_application_passwords_available() ) {
$error = new WP_Error(
'application_passwords_disabled',
__( 'Application passwords are not available.' )
);
} elseif ( ! wp_is_application_passwords_available_for_user( $user ) ) {
$error = new WP_Error(
'application_passwords_disabled_for_user',
__( 'Application passwords are not available for your account. Please contact the site administrator for assistance.' )
);
}
if ( $error ) {
/**
* Fires when an application password failed to authenticate the user.
*
* @since 5.6.0
*
* @param WP_Error $error The authentication error.
*/
do_action( 'application_password_failed_authentication', $error );
return $error;
}
/*
* Strips out anything non-alphanumeric. This is so passwords can be used with
* or without spaces to indicate the groupings for readability.
*
* Generated application passwords are exclusively alphanumeric.
*/
$password = preg_replace( '/[^a-zd]/i', '', $password );
$hashed_passwords = WP_Application_Passwords::get_user_application_passwords( $user->ID );
foreach ( $hashed_passwords as $key => $item ) {
if ( ! WP_Application_Passwords::check_password( $password, $item['password'] ) ) {
continue;
}
$error = new WP_Error();
/**
* Fires when an application password has been successfully checked as valid.
*
* This allows for plugins to add additional constraints to prevent an application password from being used.
*
* @since 5.6.0
*
* @param WP_Error $error The error object.
* @param WP_User $user The user authenticating.
* @param array $item The details about the application password.
* @param string $password The raw supplied password.
*/
do_action( 'wp_authenticate_application_password_errors', $error, $user, $item, $password );
if ( $error->has_errors() ) {
/** This action is documented in wp-includes/user.php */
do_action( 'application_password_failed_authentication', $error );
return $error;
}
WP_Application_Passwords::record_application_password_usage( $user->ID, $item['uuid'] );
/**
* Fires after an application password was used for authentication.
*
* @since 5.6.0
*
* @param WP_User $user The user who was authenticated.
* @param array $item The application password used.
*/
do_action( 'application_password_did_authenticate', $user, $item );
return $user;
}
$error = new WP_Error(
'incorrect_password',
__( 'The provided password is an invalid application password.' )
);
/** This action is documented in wp-includes/user.php */
do_action( 'application_password_failed_authentication', $error );
return $error;
}
Hooks
- do_action( ‘application_password_did_authenticate’, WP_User $user, array $item )
-
Fires after an application password was used for authentication.
- do_action( ‘application_password_failed_authentication’, WP_Error $error )
-
Fires when an application password failed to authenticate the user.
- apply_filters( ‘application_password_is_api_request’, bool $is_api_request )
-
Filters whether this is an API request that Application Passwords can be used on.
- do_action( ‘wp_authenticate_application_password_errors’, WP_Error $error, WP_User $user, array $item, string $password )
-
Fires when an application password has been successfully checked as valid.
Changelog
| Version | Description |
|---|---|
| 5.6.0 | Introduced. |
Skip to note 2 content
Mark Howells-Mead
Usage is as follows. Passing
nullas the first parameter will ensure that the result will only be a valid user if the auth username and application password match.$user = wp_authenticate_application_password(null, $_SERVER['PHP_AUTH_USER'], $_SERVER['PHP_AUTH_PW']); if ($user instanceof WP_User) { // Do authenticated stuff }This authentification will also only work by default from within a REST API request: see
$is_api_requestabove, which you can temporarily override as follows.function wpdocs_allow_application_password_auth(){ return true; } add_filter('application_password_is_api_request', 'wpdocs_allow_application_password_auth'); $user = wp_authenticate_application_password(null, $_SERVER['PHP_AUTH_USER'], $_SERVER['PHP_AUTH_PW']); remove_filter('application_password_is_api_request', 'wpdocs_allow_application_password_auth');