这几天折腾多站点,被登录问题搞得焦头烂额。在网上找了半天,扒了几篇文章。分析用户登录过程:
单个站点容易一点,如果要多站点,并且支持注册,是一个很大的麻烦。
其实WP本身就是写博客合适,并不适合做大规模的交互站点。要实现多用户功能、注册功能、好友这些的,其实不适合用这个。
还发现一个问题,注册功能不能注册到你创建的一个子站点下面,而是和子站点在等级上是平行的。在这个上面走了弯路。
- //form提交表单 提交给了http://www.febbird.net/wp-login.php
- //form提交表单 中 :
- //参数:user_login //用户登陆名
- //user_pass 密码
- //一个隐藏的input名为redirect_to 参数为http://www.febbird.net/wp-admin/ 跳转地址———— -wp - login.php分析—————————————————- -
- //验证$action是否包含‘logout’, ’lostpassword’, ’retrievepassword’, ’resetpass’, ’rp’, ’register’, ’login’,以默认为$action = ’login’; 登录屏幕 行350
- if ( !in_array($action, array(‘logout’, ’lostpassword’, ’retrievepassword’, ’resetpass’, ’rp’, ’register’, ’login’), true) && false == = has_filter(‘login_form_’ . $action) )
- $action = ’login’;
- //判断form 中method值是否等于post 行384
- $http_post = (‘POST’ == $_SERVER['REQUEST_METHOD']);
- switch ($action)
- {
- //当$action=login 和 默认为登陆 行556
- case ’login’ :
- default:
- $secure_cookie = ”;
- $interim_login = isset($_REQUEST['interim-login']);
- //如果用户希望SSL,但会议没有SSL,强制安全cookie。
- if ( !emptyempty($_POST['log']) && !force_ssl_admin() )
- {
- //获取用户名
- $user_name = sanitize_user($_POST['log']);
- //检索用户信息的登录名。并返回用户对象
- if ( $user = get_userdatabylogin($user_name) )
- {
- //get_user_option()检索用户选项,包括global、user或blog。
- if ( get_user_option(‘use_ssl’, $user->ID) )
- {
- $secure_cookie = true;
- force_ssl_admin(true);
- }
- }
- }
- //判断重定向地址是否为空 redirect_to值为http://www.febbird.net/wp-admin/
- if ( isset( $_REQUEST['redirect_to'] ) )
- {
- $redirect_to = $_REQUEST['redirect_to'];
- // Redirect to https if user wants ssl
- // 重定向到HTTPS如果用户想SSL
- if ( $secure_cookie && false != = strpos($redirect_to, ’wp-admin’) )
- $redirect_to = preg_replace(‘|^http://|’, ’https://’, $redirect_to);
- }
- else
- {
- //admin_url() 返回 管理员后台地址 http://www.febbird.net/wp-admin/
- $redirect_to = admin_url();
- }
- //再次认证 $_REQUEST['reauth'] 为空 $reauth值为false
- $reauth = emptyempty($_REQUEST['reauth']) ? false : true;
- if ( !$secure_cookie && is_ssl() && force_ssl_login() && !force_ssl_admin() && ( 0 != = strpos($redirect_to, ’https’) ) && ( 0 == = strpos($redirect_to, ’http’) ) )
- $secure_cookie = false;
- //wp_signon授权给用户并可记住该用户名称 $secure_cookie为空
- $user = wp_signon(”, $secure_cookie);
- //返回 $redirect_to= http://www.febbird.net/wp-admin/
- $redirect_to = apply_filters(‘login_redirect’, $redirect_to, isset( $_REQUEST['redirect_to'] ) ? $_REQUEST['redirect_to'] : ”, $user);
- // 判断$user是否有错误
- // $user值为object(WP_Error)#3813 (2) { ["errors"]=> array(0) { } ["error_data"]=> array(0) { } }
- // $user为空
- // $reauth值为false
- if ( !is_wp_error($user) && !$reauth )
- {
- if ( $interim_login )
- {
- $message = ’<p>’ . __(‘You have logged in successfully.’) . ’</p>’;
- login_header( ”, $message );
- ? >
- < script type = “text/javascript” > setTimeout( function()
- {
- window.close()
- }, 8000);
- < / script >
- < p class = “alignright” >
- < input type = “button” class = “button-primary” value = “<?php esc_attr_e(‘Close’); ?>” onclick = “window.close()” / > < / p >
- < / div > < / body > < / html >
- <? php exit;
- }
- //判断 $redirect_to是否为空
- if ( ( emptyempty( $redirect_to ) || $redirect_to == ’wp-admin/’ || $redirect_to == admin_url() ) )
- {
- // 如果用户不属于一个博客,将它们发送到用户管理员。如果用户不能编辑岗位,送他们到他们的个人资料。
- // is_multisite()判断是否启用了多站点
- // get_active_blog_for_user 为用户获取活动的博客-可以是主博客或博客列表
- if ( is_multisite() && !get_active_blog_for_user($user->id) )
- $redirect_to = user_admin_url();
- elseif ( is_multisite() && !$user->has_cap(‘read’) )
- $redirect_to = get_dashboard_url( $user->id );
- elseif ( !$user->has_cap(‘edit_posts’) )
- $redirect_to = admin_url(‘profile.php’);
- }
- //重定向到其它URL的安全方式。保证结果HTTP定位信息头的合法性
- wp_safe_redirect($redirect_to);
- exit();
- }
- }
- }
- }
- //判断重定向地址是否为空 redirect_to值为http://www.febbird.net/wp-admin/ 行573
- if ( isset( $_REQUEST['redirect_to'] ) )
- {
- $redirect_to = $_REQUEST['redirect_to'];
- //重定向到HTTPS如果用户想SSL
- if ( $secure_cookie && false != = strpos($redirect_to, ’wp-admin’) )
- $redirect_to = preg_replace(‘|^http://|’, ’https://’, $redirect_to);
- }
- else
- {
- //admin_url() 返回 管理员后台地址 http://www.febbird.net/wp-admin/
- $redirect_to = admin_url();
- }
- //判断重定向地址是否为空 redirect_to值为http://www.febbird.net/wp-admin/ 行577
- if ( isset( $_REQUEST['redirect_to'] ) )
- {
- $redirect_to = $_REQUEST['redirect_to'];
- // 重定向到HTTPS如果用户想SSL
- if ( $secure_cookie && false != = strpos($redirect_to, ’wp-admin’) )
- $redirect_to = preg_replace(‘|^http://|’, ’https://’, $redirect_to);
- }
- else
- {
- //admin_url() 返回 管理员后台地址 http://www.febbird.net/wp-admin/
- $redirect_to = admin_url();
- }
- //再次认证 $_REQUEST['reauth'] 为空 $reauth值为false
- $reauth = emptyempty($_REQUEST['reauth']) ? false : true;
- //判断 $redirect_to是否为空 行617
- if ( ( emptyempty( $redirect_to ) || $redirect_to == ’wp-admin/’ || $redirect_to == admin_url() ) )
- {
- // is_multisite()判断是否启用了多站点
- // get_active_blog_for_user 为用户获取活动的博客-可以是主博客或博客列表
- if ( is_multisite() && !get_active_blog_for_user($user->id) )
- $redirect_to = user_admin_url();
- elseif ( is_multisite() && !$user->has_cap(‘read’) )
- $redirect_to = get_dashboard_url( $user->id );
- elseif ( !$user->has_cap(‘edit_posts’) )
- $redirect_to = admin_url(‘profile.php’);
- }
- //重定向到其它URL的安全方式。保证结果HTTP定位信息头的合法性
- wp_safe_redirect($redirect_to);
- exit();
- }
- ———— -get_userdatabylogin()函数定义 在 wp - includes / pluggable.php 行214 ——
- //$user_login用户信息的登录名。并返回用户对象
- function get_userdatabylogin($user_login)
- {
- return get_user_by(‘login’, $user_login);//定义get_user_by() 在 wp-includes/pluggable.php 行169
- }
- //检索一个特定领域的用户
- //定义get_user_by() 在 wp-includes/pluggable.php 行169
- //$field=login 条件 $value=$user_login 登陆名
- function get_user_by($field, $value)
- {
- global $wpdb;
- switch ($field)
- {
- case ’id’:
- //get_userdata()返回的对象中含有用户相关信息,用户编号被传递
- return get_userdata($value);
- break;
- case ’slug’:
- $user_id = wp_cache_get($value, ’userslugs’);
- $field = ’user_nicename’;
- break;
- case ’email’:
- $user_id = wp_cache_get($value, ’useremail’);
- $field = ’user_email’;
- break;
- //登陆
- case ’login’:
- //sanitize_user 消除用户名中的不安全字符
- $value = sanitize_user( $value );
- // wp_cache_get()如果缓存对象未过期,该函数返回缓存对象的值。否则返回false。
- //在 wp-includes/cache.php 行90
- $user_id = wp_cache_get($value, ’userlogins’);
- $field = ’user_login’;
- break;
- default:
- return false;
- }
- if ( false != = $user_id )
- return get_userdata($user_id);
- if ( !$user = $wpdb->get_row( $wpdb->prepare(“SELECT * FROM $wpdb->users WHERE $field = %s”, $value) ) )
- return false;
- _fill_user($user);
- return $user;
- }
- // wp_cache_get()如果缓存对象未过期,该函数返回缓存对象的值。否则返回false。
- //在 wp-includes/cache.php 缓存类 行90
- function wp_cache_get($id, $flag = ”)
- {
- global $wp_object_cache;
- //get() 在wp-includes/cache.php 行347
- return $wp_object_cache->get($id, $flag);
- }
- //取得存在的缓存数据 ,根据id的分组搜索数据,如果数据存在,返回数据
- function get($id, $group = ’default‘)
- {
- if ( emptyempty ($group) )
- $group = ’default‘;
- if ( isset ($this->cache[$group][$id]) )
- {
- $this->cache_hits += 1;
- if ( is_object($this->cache[$group][$id]) )
- return wp_clone($this->cache[$group][$id]);
- else
- return $this->cache[$group][$id];
- }
- if ( isset ($this->non_existent_objects[$group][$id]) )
- return false;
- $this->non_existent_objects[$group][$id] = true;
- $this->cache_misses += 1;
- return false;
- }
- ——————– -get_user_option()在wp - includes / user.php 行250——————– -
- // 检索用户选项,包括global、user或blog。
- // $option 用户选项名称 $user 用户id
- // $deprecated 如果之前的用户选项不存在,是否需要在选项表中查找一个选项
- function get_user_option( $option, $user = 0, $deprecated = ” )
- {
- global $wpdb;
- //判断deprecated是否为空
- if ( !emptyempty( $deprecated ) )
- _deprecated_argument( __FUNCTION__, ’3.0′ );
- //判断$user对象是否为空,为空是执行以下代码
- if ( emptyempty($user) )
- {
- //在数据库中更新(或创建)用户
- $user = wp_get_current_user();
- //返回用户id
- $user = $user->ID;
- }
- //返回的对象中含有用户相关信息,$user用户id
- $user = get_userdata($user);
- // $key 中不能有-
- $key = str_replace(‘-’, ”, $option);
- if ( isset( $user-> {$wpdb->prefix . $key} ) ) // Blog specific
- $result = $user-> {$wpdb->prefix . $key};
- elseif ( isset( $user-> {$key} ) ) // User specific and cross-blog
- $result = $user-> {$key};
- else
- $result = false;
- return apply_filters(“get_user_option_{$option}”, $result, $option, $user);
- }
- //验证用户使用用户名和密码。 wp-includes/user.php 行 73
- add_filter(‘authenticate’, ’wp_authenticate_username_password’, 20, 3);
- //对用户密码相对应的验证如执行对空用户名和密码的检查。 wp-includes/user.php 行 75
- // $user 用户对象 $username 用户名 $password 密码
- function wp_authenticate_username_password($user, $username, $password)
- {
- //判断$用户对象是否存在,如果存在返回
- if ( is_a($user, ’WP_User’) )
- {
- return $user;
- }
- //判断用户或密码为空执行
- if ( emptyempty($username) || emptyempty($password) )
- {
- $error = new WP_Error();
- //判断用户名为空
- if ( emptyempty($username) )
- $error->add(‘empty_username’, __(‘<strong>ERROR</strong>: The username field is emptyempty.’));
- //判断密码为空
- if ( emptyempty($password) )
- $error->add(‘empty_password’, __(‘<strong>ERROR</strong>: The password field is emptyempty.’));
- return $error;
- }
- $userdata = get_user_by(‘login’, $username);
- //验证用户名是否正确,如果用户名不正确执行
- if ( !$userdata )
- return new WP_Error(‘invalid_username’, sprintf(__(‘<strong>ERROR</strong>: Invalid username. <a href=“%s” title=“Password Lost and Found”>Lost your password</a>?’), site_url(‘wp-login.php?action=lostpassword’, ’login’)));
- //判断是不是多站点
- if ( is_multisite() )
- {
- //spam= 1 时,提示 您的账户已被标记为垃圾账户。
- if ( 1 == $userdata->spam)
- return new WP_Error(‘invalid_username’, __(‘<strong>ERROR</strong>: Your account has been marked as a spammer.’));
- //标识是不是垃圾博文
- if ( !is_super_admin( $userdata->ID ) && isset($userdata->primary_blog) )
- {
- $details = get_blog_details( $userdata->primary_blog );
- if ( is_object( $details ) && $details->spam == 1 )
- return new WP_Error(‘blog_suspended’, __(‘Site Suspended.’));
- }
- }
- $userdata = apply_filters(‘wp_authenticate_user’, $userdata, $password);
- if ( is_wp_error($userdata) )
- return $userdata;
- //验证密码是否正确,如果密码不正确执行
- if ( !wp_check_password($password, $userdata->user_pass, $userdata->ID) )
- return new WP_Error( ’incorrect_password’, sprintf( __( ’<strong>ERROR</strong>: The password you entered for the username <strong>%1$s</strong> is incorrect. <a href=“%2$s” title=“Password Lost and Found”>Lost your password</a>?’ ),
- $username, site_url( ’wp-login.php?action=lostpassword’, ’login’ ) ) );
- //wp-includes/capabilities.php 创建WP_User类行363
- //根据 用户id 实例化用户对象 并返回用户数据
- $user = new WP_User($userdata->ID);
- return $user;