各位观众老爷们,晚上好! 今天咱就来唠唠 WordPress 里那个神秘又重要的 wp_set_auth_cookie()
函数,看看它到底是怎么把咱们登录状态“烙印”在浏览器上的,也就是设置用户登录会话的 Cookie 的。 准备好了吗? 咱们这就开讲!
一、Cookie 是个啥?为啥要用它?
在深入源码之前,先得搞清楚 Cookie 是个什么玩意儿。 简单来说,Cookie 就是服务器存储在咱们浏览器上的一小段文本信息。 每次咱们再访问同一个网站时,浏览器都会自动把这些 Cookie 发给服务器。
为啥要用 Cookie 呢? 因为 HTTP 协议是无状态的,也就是说,服务器记不住你上次是谁。 想象一下,你登录了一个网站,点了个商品加入购物车,然后你点到另一个页面,如果服务器不记得你已经登录了,那购物车里的商品岂不是就丢了? 这就尴尬了!
Cookie 就解决了这个问题。 通过 Cookie,服务器可以记住你的登录状态、购物车里的商品、个性化设置等等。
二、wp_set_auth_cookie()
函数: 登录的“烙印师”
wp_set_auth_cookie()
函数的作用就是设置验证 Cookie,告诉浏览器 "嘿,这个用户已经登录了,记住他!"。 它是 WordPress 用户验证机制的核心部分。
三、源码剖析: 一步一步揭秘 Cookie 的诞生
咱们现在就来扒一扒 wp_set_auth_cookie()
函数的源码,看看它到底是怎么“烙印” Cookie 的。
/**
* Sets the authentication cookies.
*
* Stores the authentication details in a cookie. The cookie is used to
* automatically sign in the user when they return to the site.
*
* @since 2.5.0
*
* @param int $user_id User ID.
* @param bool $remember Whether to remember the user. Default is false.
* @param mixed $expiration Optional. Unix timestamp for when the cookie expires.
* If `$remember` is true, defaults to 14 days from now.
* If `$remember` is false, defaults to 12 hours from now.
* @param string $scheme Optional. Scheme to use. Default is 'auth'. Accepts 'auth', 'secure_auth', or 'logged_in'.
*/
function wp_set_auth_cookie( $user_id, $remember = false, $expiration = null, $scheme = 'auth' ) {
$secure = is_ssl();
if ( ! $expiration ) {
if ( $remember ) {
$expiration = time() + (int) apply_filters( 'auth_cookie_expiration', 14 * DAY_IN_SECONDS, $user_id, $remember );
} else {
$expiration = time() + (int) apply_filters( 'auth_cookie_expiration', 12 * HOUR_IN_SECONDS, $user_id, $remember );
}
} else {
$expiration = (int) $expiration;
}
$auth_cookie_name = AUTH_COOKIE;
$scheme_cookie_name = $scheme . '_cookie';
$logged_in_cookie = LOGGED_IN_COOKIE;
if ( 'secure_auth' === $scheme ) {
$auth_cookie_name = SECURE_AUTH_COOKIE;
$logged_in_cookie = SECURE_LOGGED_IN_COOKIE;
$secure = true;
} elseif ( 'logged_in' === $scheme ) {
$auth_cookie_name = LOGGED_IN_COOKIE;
$secure = apply_filters( 'secure_logged_in_cookie', $secure, $user_id, $remember );
}
$auth_cookie = wp_generate_auth_cookie( $user_id, $expiration, $scheme );
$scheme_cookie = wp_generate_auth_cookie( $user_id, $expiration, $scheme, 'token' );
setcookie( $auth_cookie_name, $auth_cookie, $expiration, COOKIEPATH, COOKIE_DOMAIN, $secure, true );
setcookie( $scheme_cookie_name, $scheme_cookie, $expiration, COOKIEPATH, COOKIE_DOMAIN, $secure, true );
if ( $remember ) {
setcookie( 'wp-saving-post', 'checking', time() + 30, ADMIN_COOKIE_PATH, COOKIE_DOMAIN, $secure, true );
}
/**
* Fires immediately after the authentication cookies are set.
*
* @since 3.7.0
*
* @param int $user_id User ID.
* @param bool $remember Whether to remember the user.
* @param string $expiration The time the auth cookie expires as a Unix timestamp.
* @param string $scheme The scheme to use. Default is 'auth'.
*/
do_action( 'set_auth_cookie', $user_id, $remember, $expiration, $scheme );
}
咱们一行一行地拆解:
-
参数解析:
$user_id
: 用户 ID,这个是必须的,告诉函数你要给哪个用户设置 Cookie。$remember
: 是否“记住我”,也就是是否设置一个有效期更长的 Cookie。 默认是false
,也就是不记住。$expiration
: Cookie 的过期时间,Unix 时间戳格式。 如果不传,函数会根据$remember
的值来设置默认的过期时间。 记住我,默认14天过期,否则12小时。$scheme
: Cookie 的方案,默认是auth
。 还可以是secure_auth
或logged_in
。 这个参数决定了 Cookie 的名称。
-
判断是否是安全连接(HTTPS):
$secure = is_ssl();
is_ssl()
函数会判断当前是否是 HTTPS 连接。 如果是,$secure
就为true
,否则为false
。 这个变量会影响 Cookie 的secure
标志,后面会讲到。 -
设置过期时间:
if ( ! $expiration ) { if ( $remember ) { $expiration = time() + (int) apply_filters( 'auth_cookie_expiration', 14 * DAY_IN_SECONDS, $user_id, $remember ); } else { $expiration = time() + (int) apply_filters( 'auth_cookie_expiration', 12 * HOUR_IN_SECONDS, $user_id, $remember ); } } else { $expiration = (int) $expiration; }
这段代码根据
$remember
的值来设置 Cookie 的过期时间。 如果$remember
为true
,则过期时间为 14 天后,否则为 12 小时后。 注意,这里使用了apply_filters()
函数,允许开发者通过过滤器来修改默认的过期时间。参数 说明 time()
当前时间的 Unix 时间戳 DAY_IN_SECONDS
WordPress 定义的常量,表示一天有多少秒 (86400) HOUR_IN_SECONDS
WordPress 定义的常量,表示一小时有多少秒 (3600) apply_filters()
WordPress 的过滤器函数,允许开发者修改变量的值 auth_cookie_expiration
过滤器名称,用于修改 Cookie 的过期时间 $user_id
用户 ID $remember
是否“记住我” -
确定 Cookie 名称:
$auth_cookie_name = AUTH_COOKIE; $scheme_cookie_name = $scheme . '_cookie'; $logged_in_cookie = LOGGED_IN_COOKIE; if ( 'secure_auth' === $scheme ) { $auth_cookie_name = SECURE_AUTH_COOKIE; $logged_in_cookie = SECURE_LOGGED_IN_COOKIE; $secure = true; } elseif ( 'logged_in' === $scheme ) { $auth_cookie_name = LOGGED_IN_COOKIE; $secure = apply_filters( 'secure_logged_in_cookie', $secure, $user_id, $remember ); }
这段代码根据
$scheme
的值来确定 Cookie 的名称。 WordPress 定义了几个常量来表示不同的 Cookie 名称:AUTH_COOKIE
: 默认的验证 Cookie 名称。SECURE_AUTH_COOKIE
: 用于 HTTPS 连接的验证 Cookie 名称。LOGGED_IN_COOKIE
: 用于“记住我”功能的 Cookie 名称。
如果
$scheme
是secure_auth
,则使用SECURE_AUTH_COOKIE
,并且强制$secure
为true
,因为secure_auth
只能用于 HTTPS 连接。
如果$scheme
是logged_in
,则使用LOGGED_IN_COOKIE
,并且允许开发者通过secure_logged_in_cookie
过滤器来修改$secure
的值。 -
生成 Cookie 值:
$auth_cookie = wp_generate_auth_cookie( $user_id, $expiration, $scheme ); $scheme_cookie = wp_generate_auth_cookie( $user_id, $expiration, $scheme, 'token' );
wp_generate_auth_cookie()
函数用于生成 Cookie 的值。 这个函数会根据用户 ID、过期时间和方案生成一个加密的字符串。 咱们后面会详细讲这个函数。 生成了两个cookie,一个auth_cookie,一个scheme_cookie。 -
设置 Cookie:
setcookie( $auth_cookie_name, $auth_cookie, $expiration, COOKIEPATH, COOKIE_DOMAIN, $secure, true ); setcookie( $scheme_cookie_name, $scheme_cookie, $expiration, COOKIEPATH, COOKIE_DOMAIN, $secure, true );
setcookie()
函数是 PHP 内置的函数,用于设置 Cookie。 咱们来看看它的参数:$auth_cookie_name
: Cookie 的名称。$auth_cookie
: Cookie 的值。$expiration
: Cookie 的过期时间,Unix 时间戳格式。COOKIEPATH
: Cookie 的路径,通常是网站的根目录。 WordPress 定义了COOKIEPATH
常量。COOKIE_DOMAIN
: Cookie 的域名,通常是网站的域名。 WordPress 定义了COOKIE_DOMAIN
常量。$secure
: 是否只允许 HTTPS 连接访问 Cookie。 如果为true
,则只有 HTTPS 连接才能访问 Cookie。true
:httponly
标志。 如果为true
,则 JavaScript 无法访问 Cookie,可以防止 XSS 攻击。
所以,这行代码的意思就是:设置一个名为
$auth_cookie_name
的 Cookie,值为$auth_cookie
,过期时间为$expiration
,路径为COOKIEPATH
,域名为COOKIE_DOMAIN
,只允许 HTTPS 连接访问(如果$secure
为true
),并且 JavaScript 无法访问。同理,第二行代码设置了scheme cookie。
-
设置 "wp-saving-post" Cookie (如果需要 "记住我"):
if ( $remember ) { setcookie( 'wp-saving-post', 'checking', time() + 30, ADMIN_COOKIE_PATH, COOKIE_DOMAIN, $secure, true ); }
如果设置了 "记住我" 功能,这段代码会设置一个名为
wp-saving-post
的 Cookie。 这个 Cookie 的作用是防止用户在编辑文章时丢失数据。 它的过期时间是 30 秒,路径是ADMIN_COOKIE_PATH
,也就是 WordPress 后台的路径。 -
触发
set_auth_cookie
动作:do_action( 'set_auth_cookie', $user_id, $remember, $expiration, $scheme );
do_action()
函数是 WordPress 的动作钩子函数,用于触发一个动作。 这里的动作是set_auth_cookie
,允许开发者在设置 Cookie 之后执行一些自定义的操作。参数 说明 set_auth_cookie
动作名称 $user_id
用户 ID $remember
是否“记住我” $expiration
Cookie 的过期时间,Unix 时间戳格式 $scheme
Cookie 的方案
四、wp_generate_auth_cookie()
函数: Cookie 值的“加密大师”
咱们再来看看 wp_generate_auth_cookie()
函数,它是如何生成 Cookie 值的。
/**
* Generates an authentication cookie.
*
* @since 2.6.0
*
* @param int $user_id User ID.
* @param int $expiration Unix timestamp for when the cookie expires.
* @param string $scheme Authentication scheme. Default is 'auth'. Accepts 'auth', 'secure_auth', or 'logged_in'.
* @param string $token_type Optional. Type of token to generate. Accepts 'auth' or 'token'. Default is 'auth'.
* @return string Authentication cookie.
*/
function wp_generate_auth_cookie( $user_id, $expiration, $scheme = 'auth', $token_type = 'auth' ) {
$key = wp_hash( $user_id . '|' . $expiration . '|' . $scheme . '|' . $token_type, $scheme );
$hash = hash_hmac( 'md5', $user_id . '|' . $expiration . '|' . $scheme . '|' . $token_type, $key );
$cookie = $user_id . '|' . $expiration . '|' . $hash;
return $cookie;
}
-
生成 Key:
$key = wp_hash( $user_id . '|' . $expiration . '|' . $scheme . '|' . $token_type, $scheme );
wp_hash()
函数用于生成一个唯一的 Key。 它的第一个参数是一个字符串,由用户 ID、过期时间、方案和token类型拼接而成。 第二个参数是方案,用于确定使用哪个盐值。 -
生成 Hash:
$hash = hash_hmac( 'md5', $user_id . '|' . $expiration . '|' . $scheme . '|' . $token_type, $key );
hash_hmac()
函数用于生成一个 HMAC (Hash-based Message Authentication Code)。 它的第一个参数是哈希算法,这里是md5
。 第二个参数是消息,也就是用户 ID、过期时间和方案拼接成的字符串。 第三个参数是 Key,也就是上一步生成的 Key。HMAC 是一种消息认证码算法,可以防止消息被篡改。
-
拼接 Cookie 值:
$cookie = $user_id . '|' . $expiration . '|' . $hash;
最后,将用户 ID、过期时间和 Hash 拼接成一个字符串,作为 Cookie 的值。
五、总结:wp_set_auth_cookie()
的工作流程
咱们来总结一下 wp_set_auth_cookie()
函数的工作流程:
- 接收用户 ID、是否“记住我”、过期时间和方案等参数。
- 根据是否是 HTTPS 连接,设置
$secure
变量。 - 根据
$remember
的值,设置 Cookie 的过期时间。 - 根据
$scheme
的值,确定 Cookie 的名称。 - 调用
wp_generate_auth_cookie()
函数生成 Cookie 的值。 - 调用
setcookie()
函数设置 Cookie。 - 如果需要“记住我”,设置
wp-saving-post
Cookie。 - 触发
set_auth_cookie
动作。
六、安全性考量
WordPress 的 Cookie 安全性设计还是比较严谨的,主要体现在以下几个方面:
- HTTPS 支持: 通过
$secure
标志,可以确保 Cookie 只能在 HTTPS 连接中传输,防止被窃听。 httponly
标志: 通过httponly
标志,可以防止 JavaScript 访问 Cookie,防止 XSS 攻击。- HMAC 算法: 通过 HMAC 算法,可以防止 Cookie 被篡改。
- 盐值: 通过盐值,可以增加 Cookie 的破解难度。
七、代码演示: 如何使用 wp_set_auth_cookie()
// 假设用户登录验证成功
$user_id = 123; // 用户 ID
$remember = true; // 记住我
// 设置验证 Cookie
wp_set_auth_cookie( $user_id, $remember );
// 重定向到首页
wp_redirect( home_url() );
exit;
这段代码演示了如何使用 wp_set_auth_cookie()
函数来设置验证 Cookie。 首先,假设用户登录验证成功,获取到用户 ID。 然后,设置 $remember
变量为 true
,表示要“记住我”。 最后,调用 wp_set_auth_cookie()
函数设置 Cookie,并重定向到首页。
八、wp_clear_auth_cookie()
函数:告别 Cookie
与 wp_set_auth_cookie()
相对应,WordPress 提供了 wp_clear_auth_cookie()
函数来清除验证 Cookie,也就是用户登出。
/**
* Clears the authentication cookies.
*
* @since 2.5.0
*/
function wp_clear_auth_cookie() {
/**
* Fires before the authentication cookies are cleared.
*
* @since 3.0.0
*
* @param string $scheme The scheme to use. Default is 'auth'.
*/
do_action( 'clear_auth_cookie', 'auth' );
_wp_clear_auth_cookie();
}
可以看到,它调用了 _wp_clear_auth_cookie()
函数来完成实际的清除工作,并触发了 clear_auth_cookie
动作。
/**
* Clears all authentication cookies.
*
* @access private
* @since 3.5.0
*/
function _wp_clear_auth_cookie() {
$secure = is_ssl();
setcookie( AUTH_COOKIE, ' ', time() - YEAR_IN_SECONDS, COOKIEPATH, COOKIE_DOMAIN, $secure, true );
setcookie( SECURE_AUTH_COOKIE, ' ', time() - YEAR_IN_SECONDS, COOKIEPATH, COOKIE_DOMAIN, true, true );
setcookie( LOGGED_IN_COOKIE, ' ', time() - YEAR_IN_SECONDS, COOKIEPATH, COOKIE_DOMAIN, $secure, true );
setcookie( AUTH_COOKIE, ' ', time() - YEAR_IN_SECONDS, SITECOOKIEPATH, COOKIE_DOMAIN, $secure, true );
setcookie( SECURE_AUTH_COOKIE, ' ', time() - YEAR_IN_SECONDS, SITECOOKIEPATH, COOKIE_DOMAIN, true, true );
setcookie( LOGGED_IN_COOKIE, ' ', time() - YEAR_IN_SECONDS, SITECOOKIEPATH, COOKIE_DOMAIN, $secure, true );
}
_wp_clear_auth_cookie()
函数的原理很简单,就是将所有可能的验证 Cookie 的值设置为空,并将过期时间设置为过去的时间,从而使浏览器删除这些 Cookie。 它不仅清除了普通的 Cookie,还清除了 Secure Cookie 和 Logged-in Cookie,并且考虑到了 Cookie 路径的问题,分别在 COOKIEPATH
和 SITECOOKIEPATH
下都进行了清除操作。
九、总结的总结:Cookie 是 WordPress 登录验证的基石
总而言之,wp_set_auth_cookie()
函数是 WordPress 登录验证的核心,它通过设置 Cookie 来实现用户登录状态的保持。 理解了这个函数的工作原理,就能更好地理解 WordPress 的用户验证机制,也能更好地保护网站的安全。 希望今天的讲解对大家有所帮助!
感谢各位观众老爷的捧场! 咱们下期再见!