* Needed for the login grace period in wp_validate_auth_cookie().
$expire = $expiration + ( 12 * HOUR_IN_SECONDS );
/** This filter is documented in wp-includes/pluggable.php */
$expiration = time() + apply_filters( 'auth_cookie_expiration', 2 * DAY_IN_SECONDS, $user_id, $remember );
// Front-end cookie is secure when the auth cookie is secure and the site's home URL uses HTTPS.
$secure_logged_in_cookie = $secure && 'https' === parse_url( get_option( 'home' ), PHP_URL_SCHEME );
* Filters whether the auth cookie should only be sent over HTTPS.
* @param bool $secure Whether the cookie should only be sent over HTTPS.
* @param int $user_id User ID.
$secure = apply_filters( 'secure_auth_cookie', $secure, $user_id );
* Filters whether the logged in cookie should only be sent over HTTPS.
* @param bool $secure_logged_in_cookie Whether the logged in cookie should only be sent over HTTPS.
* @param int $user_id User ID.
* @param bool $secure Whether the auth cookie should only be sent over HTTPS.
$secure_logged_in_cookie = apply_filters( 'secure_logged_in_cookie', $secure_logged_in_cookie, $user_id, $secure );
$auth_cookie_name = SECURE_AUTH_COOKIE;
$auth_cookie_name = AUTH_COOKIE;
$manager = WP_Session_Tokens::get_instance( $user_id );
$token = $manager->create( $expiration );
$auth_cookie = wp_generate_auth_cookie( $user_id, $expiration, $scheme, $token );
$logged_in_cookie = wp_generate_auth_cookie( $user_id, $expiration, 'logged_in', $token );
* Fires immediately before the authentication cookie is set.
* @since 4.9.0 The `$token` parameter was added.
* @param string $auth_cookie Authentication cookie value.
* @param int $expire The time the login grace period expires as a UNIX timestamp.
* Default is 12 hours past the cookie's expiration time.
* @param int $expiration The time when the authentication cookie expires as a UNIX timestamp.
* Default is 14 days from now.
* @param int $user_id User ID.
* @param string $scheme Authentication scheme. Values include 'auth' or 'secure_auth'.
* @param string $token User's session token to use for this cookie.
do_action( 'set_auth_cookie', $auth_cookie, $expire, $expiration, $user_id, $scheme, $token );
* Fires immediately before the logged-in authentication cookie is set.
* @since 4.9.0 The `$token` parameter was added.
* @param string $logged_in_cookie The logged-in cookie value.
* @param int $expire The time the login grace period expires as a UNIX timestamp.
* Default is 12 hours past the cookie's expiration time.
* @param int $expiration The time when the logged-in authentication cookie expires as a UNIX timestamp.
* Default is 14 days from now.
* @param int $user_id User ID.
* @param string $scheme Authentication scheme. Default 'logged_in'.
* @param string $token User's session token to use for this cookie.
do_action( 'set_logged_in_cookie', $logged_in_cookie, $expire, $expiration, $user_id, 'logged_in', $token );
* Allows preventing auth cookies from actually being sent to the client.
* @since 6.2.0 The `$expire`, `$expiration`, `$user_id`, `$scheme`, and `$token` parameters were added.
* @param bool $send Whether to send auth cookies to the client. Default true.
* @param int $expire The time the login grace period expires as a UNIX timestamp.
* Default is 12 hours past the cookie's expiration time. Zero when clearing cookies.
* @param int $expiration The time when the logged-in authentication cookie expires as a UNIX timestamp.
* Default is 14 days from now. Zero when clearing cookies.
* @param int $user_id User ID. Zero when clearing cookies.
* @param string $scheme Authentication scheme. Values include 'auth' or 'secure_auth'.
* Empty string when clearing cookies.
* @param string $token User's session token to use for this cookie. Empty string when clearing cookies.
if ( ! apply_filters( 'send_auth_cookies', true, $expire, $expiration, $user_id, $scheme, $token ) ) {
setcookie( $auth_cookie_name, $auth_cookie, $expire, PLUGINS_COOKIE_PATH, COOKIE_DOMAIN, $secure, true );
setcookie( $auth_cookie_name, $auth_cookie, $expire, ADMIN_COOKIE_PATH, COOKIE_DOMAIN, $secure, true );
setcookie( LOGGED_IN_COOKIE, $logged_in_cookie, $expire, COOKIEPATH, COOKIE_DOMAIN, $secure_logged_in_cookie, true );
if ( COOKIEPATH !== SITECOOKIEPATH ) {
setcookie( LOGGED_IN_COOKIE, $logged_in_cookie, $expire, SITECOOKIEPATH, COOKIE_DOMAIN, $secure_logged_in_cookie, true );
if ( ! function_exists( 'wp_clear_auth_cookie' ) ) :
* Removes all of the cookies associated with authentication.
function wp_clear_auth_cookie() {
* Fires just before the authentication cookies are cleared.
do_action( 'clear_auth_cookie' );
/** This filter is documented in wp-includes/pluggable.php */
if ( ! apply_filters( 'send_auth_cookies', true, 0, 0, 0, '', '' ) ) {
setcookie( AUTH_COOKIE, ' ', time() - YEAR_IN_SECONDS, ADMIN_COOKIE_PATH, COOKIE_DOMAIN );
setcookie( SECURE_AUTH_COOKIE, ' ', time() - YEAR_IN_SECONDS, ADMIN_COOKIE_PATH, COOKIE_DOMAIN );
setcookie( AUTH_COOKIE, ' ', time() - YEAR_IN_SECONDS, PLUGINS_COOKIE_PATH, COOKIE_DOMAIN );
setcookie( SECURE_AUTH_COOKIE, ' ', time() - YEAR_IN_SECONDS, PLUGINS_COOKIE_PATH, COOKIE_DOMAIN );
setcookie( LOGGED_IN_COOKIE, ' ', time() - YEAR_IN_SECONDS, COOKIEPATH, COOKIE_DOMAIN );
setcookie( LOGGED_IN_COOKIE, ' ', time() - YEAR_IN_SECONDS, SITECOOKIEPATH, COOKIE_DOMAIN );
setcookie( 'wp-settings-' . get_current_user_id(), ' ', time() - YEAR_IN_SECONDS, SITECOOKIEPATH );
setcookie( 'wp-settings-time-' . get_current_user_id(), ' ', time() - YEAR_IN_SECONDS, SITECOOKIEPATH );
setcookie( AUTH_COOKIE, ' ', time() - YEAR_IN_SECONDS, COOKIEPATH, COOKIE_DOMAIN );
setcookie( AUTH_COOKIE, ' ', time() - YEAR_IN_SECONDS, SITECOOKIEPATH, COOKIE_DOMAIN );
setcookie( SECURE_AUTH_COOKIE, ' ', time() - YEAR_IN_SECONDS, COOKIEPATH, COOKIE_DOMAIN );
setcookie( SECURE_AUTH_COOKIE, ' ', time() - YEAR_IN_SECONDS, SITECOOKIEPATH, COOKIE_DOMAIN );
setcookie( USER_COOKIE, ' ', time() - YEAR_IN_SECONDS, COOKIEPATH, COOKIE_DOMAIN );
setcookie( PASS_COOKIE, ' ', time() - YEAR_IN_SECONDS, COOKIEPATH, COOKIE_DOMAIN );
setcookie( USER_COOKIE, ' ', time() - YEAR_IN_SECONDS, SITECOOKIEPATH, COOKIE_DOMAIN );
setcookie( PASS_COOKIE, ' ', time() - YEAR_IN_SECONDS, SITECOOKIEPATH, COOKIE_DOMAIN );
setcookie( 'wp-postpass_' . COOKIEHASH, ' ', time() - YEAR_IN_SECONDS, COOKIEPATH, COOKIE_DOMAIN );
if ( ! function_exists( 'is_user_logged_in' ) ) :
* Determines whether the current visitor is a logged in user.
* For more information on this and similar theme functions, check out
* the {@link https://developer.wordpress.org/themes/basics/conditional-tags/
* Conditional Tags} article in the Theme Developer Handbook.
* @return bool True if user is logged in, false if not logged in.
function is_user_logged_in() {
$user = wp_get_current_user();
if ( ! function_exists( 'auth_redirect' ) ) :
* Checks if a user is logged in, if not it redirects them to the login page.
* When this code is called from a page, it checks to see if the user viewing the page is logged in.
* If the user is not logged in, they are redirected to the login page. The user is redirected
* in such a way that, upon logging in, they will be sent directly to the page they were originally
function auth_redirect() {
$secure = ( is_ssl() || force_ssl_admin() );
* Filters whether to use a secure authentication redirect.
* @param bool $secure Whether to use a secure authentication redirect. Default false.
$secure = apply_filters( 'secure_auth_redirect', $secure );
// If https is required and request is http, redirect.
if ( $secure && ! is_ssl() && str_contains( $_SERVER['REQUEST_URI'], 'wp-admin' ) ) {
if ( str_starts_with( $_SERVER['REQUEST_URI'], 'http' ) ) {
wp_redirect( set_url_scheme( $_SERVER['REQUEST_URI'], 'https' ) );
wp_redirect( 'https://' . $_SERVER['HTTP_HOST'] . $_SERVER['REQUEST_URI'] );
* Filters the authentication redirect scheme.
* @param string $scheme Authentication redirect scheme. Default empty.
$scheme = apply_filters( 'auth_redirect_scheme', '' );
$user_id = wp_validate_auth_cookie( '', $scheme );
* Fires before the authentication redirect.
* @param int $user_id User ID.
do_action( 'auth_redirect', $user_id );
// If the user wants ssl but the session is not ssl, redirect.
if ( ! $secure && get_user_option( 'use_ssl', $user_id ) && str_contains( $_SERVER['REQUEST_URI'], 'wp-admin' ) ) {
if ( str_starts_with( $_SERVER['REQUEST_URI'], 'http' ) ) {
wp_redirect( set_url_scheme( $_SERVER['REQUEST_URI'], 'https' ) );
wp_redirect( 'https://' . $_SERVER['HTTP_HOST'] . $_SERVER['REQUEST_URI'] );
return; // The cookie is good, so we're done.
// The cookie is no good, so force login.
if ( str_contains( $_SERVER['REQUEST_URI'], '/options.php' ) && wp_get_referer() ) {
$redirect = wp_get_referer();
$redirect = set_url_scheme( 'http://' . $_SERVER['HTTP_HOST'] . $_SERVER['REQUEST_URI'] );
$login_url = wp_login_url( $redirect, true );
wp_redirect( $login_url );
if ( ! function_exists( 'check_admin_referer' ) ) :
* Ensures intent by verifying that a user was referred from another admin page with the correct security nonce.
* This function ensures the user intends to perform a given action, which helps protect against clickjacking style
* attacks. It verifies intent, not authorization, therefore it does not verify the user's capabilities. This should
* be performed with `current_user_can()` or similar.
* If the nonce value is invalid, the function will exit with an "Are You Sure?" style message.
* @since 2.5.0 The `$query_arg` parameter was added.
* @param int|string $action The nonce action.
* @param string $query_arg Optional. Key to check for nonce in `$_REQUEST`. Default '_wpnonce'.
* @return int|false 1 if the nonce is valid and generated between 0-12 hours ago,
* 2 if the nonce is valid and generated between 12-24 hours ago.
* False if the nonce is invalid.
function check_admin_referer( $action = -1, $query_arg = '_wpnonce' ) {
_doing_it_wrong( __FUNCTION__, __( 'You should specify an action to be verified by using the first parameter.' ), '3.2.0' );
$adminurl = strtolower( admin_url() );
$referer = strtolower( wp_get_referer() );
$result = isset( $_REQUEST[ $query_arg ] ) ? wp_verify_nonce( $_REQUEST[ $query_arg ], $action ) : false;
* Fires once the admin request has been validated or not.
* @param string $action The nonce action.
* @param false|int $result False if the nonce is invalid, 1 if the nonce is valid and generated between
* 0-12 hours ago, 2 if the nonce is valid and generated between 12-24 hours ago.
do_action( 'check_admin_referer', $action, $result );
if ( ! $result && ! ( -1 === $action && str_starts_with( $referer, $adminurl ) ) ) {
if ( ! function_exists( 'check_ajax_referer' ) ) :
* Verifies the Ajax request to prevent processing requests external of the blog.
* @param int|string $action Action nonce.
* @param false|string $query_arg Optional. Key to check for the nonce in `$_REQUEST` (since 2.5). If false,
* `$_REQUEST` values will be evaluated for '_ajax_nonce', and '_wpnonce'
* (in that order). Default false.
* @param bool $stop Optional. Whether to stop early when the nonce cannot be verified.
* @return int|false 1 if the nonce is valid and generated between 0-12 hours ago,
* 2 if the nonce is valid and generated between 12-24 hours ago.
* False if the nonce is invalid.
function check_ajax_referer( $action = -1, $query_arg = false, $stop = true ) {
_doing_it_wrong( __FUNCTION__, __( 'You should specify an action to be verified by using the first parameter.' ), '4.7.0' );
if ( $query_arg && isset( $_REQUEST[ $query_arg ] ) ) {
$nonce = $_REQUEST[ $query_arg ];
} elseif ( isset( $_REQUEST['_ajax_nonce'] ) ) {
$nonce = $_REQUEST['_ajax_nonce'];
} elseif ( isset( $_REQUEST['_wpnonce'] ) ) {
$nonce = $_REQUEST['_wpnonce'];
$result = wp_verify_nonce( $nonce, $action );
* Fires once the Ajax request has been validated or not.
* @param string $action The Ajax nonce action.
* @param false|int $result False if the nonce is invalid, 1 if the nonce is valid and generated between
* 0-12 hours ago, 2 if the nonce is valid and generated between 12-24 hours ago.
do_action( 'check_ajax_referer', $action, $result );
if ( $stop && false === $result ) {
if ( ! function_exists( 'wp_redirect' ) ) :
* Redirects to another page.
* Note: wp_redirect() does not exit automatically, and should almost always be
* followed by a call to `exit;`:
* Exiting can also be selectively manipulated by using wp_redirect() as a conditional
* in conjunction with the {@see 'wp_redirect'} and {@see 'wp_redirect_status'} filters:
* if ( wp_redirect( $url ) ) {
* @since 5.1.0 The `$x_redirect_by` parameter was added.
* @since 5.4.0 On invalid status codes, wp_die() is called.
* @param string $location The path or URL to redirect to.
* @param int $status Optional. HTTP response status code to use. Default '302' (Moved Temporarily).
* @param string|false $x_redirect_by Optional. The application doing the redirect or false to omit. Default 'WordPress'.
* @return bool False if the redirect was canceled, true otherwise.
function wp_redirect( $location, $status = 302, $x_redirect_by = 'WordPress' ) {
* Filters the redirect location.
* @param string $location The path or URL to redirect to.
* @param int $status The HTTP response status code to use.
$location = apply_filters( 'wp_redirect', $location, $status );
* Filters the redirect HTTP response status code to use.
* @param int $status The HTTP response status code to use.
* @param string $location The path or URL to redirect to.
$status = apply_filters( 'wp_redirect_status', $status, $location );
if ( $status < 300 || 399 < $status ) {
wp_die( __( 'HTTP redirect status code must be a redirection code, 3xx.' ) );
$location = wp_sanitize_redirect( $location );
if ( ! $is_IIS && 'cgi-fcgi' !== PHP_SAPI ) {
status_header( $status ); // This causes problems on IIS and some FastCGI setups.
* Filters the X-Redirect-By header.
* Allows applications to identify themselves when they're doing a redirect.
* @param string|false $x_redirect_by The application doing the redirect or false to omit the header.
* @param int $status Status code to use.
* @param string $location The path to redirect to.
$x_redirect_by = apply_filters( 'x_redirect_by', $x_redirect_by, $status, $location );
if ( is_string( $x_redirect_by ) ) {
header( "X-Redirect-By: $x_redirect_by" );
header( "Location: $location", true, $status );
if ( ! function_exists( 'wp_sanitize_redirect' ) ) :
* Sanitizes a URL for use in a redirect.
* @param string $location The path to redirect to.
* @return string Redirect-sanitized URL.
function wp_sanitize_redirect( $location ) {
$location = str_replace( ' ', '%20', $location );
(?: [\xC2-\xDF][\x80-\xBF] # double-byte sequences 110xxxxx 10xxxxxx
| \xE0[\xA0-\xBF][\x80-\xBF] # triple-byte sequences 1110xxxx 10xxxxxx * 2
| [\xE1-\xEC][\x80-\xBF]{2}
| \xED[\x80-\x9F][\x80-\xBF]
| [\xEE-\xEF][\x80-\xBF]{2}
| \xF0[\x90-\xBF][\x80-\xBF]{2} # four-byte sequences 11110xxx 10xxxxxx * 3
| [\xF1-\xF3][\x80-\xBF]{3}
| \xF4[\x80-\x8F][\x80-\xBF]{2}
){1,40} # ...one or more times
$location = preg_replace_callback( $regex, '_wp_sanitize_utf8_in_redirect', $location );
$location = preg_replace( '|[^a-z0-9-~+_.?#=&;,/:%!*\[\]()@]|i', '', $location );
$location = wp_kses_no_null( $location );
// Remove %0D and %0A from location.
$strip = array( '%0d', '%0a', '%0D', '%0A' );
return _deep_replace( $strip, $location );
* URL encodes UTF-8 characters in a URL.
* @see wp_sanitize_redirect()