黄聪:Wordpress二级域名共享用户cookie出现错误解决方案及WP的Cookie机制

在若干年以前,我刚开始折腾Wordpress没多久的时候,就自己摸索过 多个Wordpress网站共享一份数据表的实现方法 。这种看起来好像很高大上的类SSO功能,能够给用户在多个网站之间提供快速、无缝、透明的登录体验。

举个很简单的例子,原本有一个Wordpress网站 http://www.example.com(后称网站A) ,你突然想增加一个博客子站点 http://blog.example.com(后称网站B) ,那么原本在 网站A 注册的用户当然不想重新去 网站B 再次注册。这个时候就体现出本文要探讨的问题的价值了。

废话不多说,直接开始!

以下例子中所有的域名example.com请自行替换成你的域名

阅读本文的前提是你已经有基本的网站部署知识,会部署单个Wordpress网站,知道如何给Wordpress配置数据库信息,了解Wordpress目录结构。

部署网站A

  1. 如果还没有部署Wordpress,先按照常规方式下载源文件、配置环境(这里不赘述)。 记录好填入的数据库名、数据库用户名、数据库密码等信息,后续步骤要使用。 (备用数据A)
  2. 编辑 wp-config.php ,在任意位置添加如下内容:
define(‘COOKIE_DOMAIN‘, ‘example.com‘);
define(‘COOKIEPATH‘, ‘/‘);  

同时找到有一排形如 define(‘XXX_KEY‘, ‘xxxasdas‘) 的内容(共8行),这里是设置一些salt,用来给cookie加密。如果没有也没有关系,有的话复制这些内容,下面的步骤要使用(备用数据B)。

部署网站B

  1. 在网站B的 wp-config.php 文件中,填写与网站A一致的数据库信息(备用数据A)
  2. 与网站A一样,在任意位置添加如下内容:
 define(‘COOKIE_DOMAIN‘, ‘example.com‘);
    define(‘COOKIEPATH‘, ‘/‘);
  1. 若存在备用数据B(各种define的‘XX_KEY‘),将这些段落完整的粘贴到网站B的 wp-config.php 中。
  2. 将 $table_prefix = ‘wp_‘; 改为 $table_prefix = ‘xxx_‘; ( xxx 是任意不同于 wp 的字符串)
  3. 添加如下内容;
define(‘CUSTOM_USER_TABLE‘, ‘wp_users‘);
define(‘CUSTOM_USER_META_TABLE‘, ‘wp_postmeta‘);  

关键步骤,修改Wordpress核心文件

我知道,这很恶心,但是我debug了一晚上后,已经实在没有精力去想一个优雅的解决方案了。请各位Wordpress达人提供一个hook吧……

按理说根据上述配置就可以实现用户在 www.example.com 登录后打开blog.example.com 也自动处于登录状态了,但是现实是无情的。即使你发现两个站点下均存在 wordpress_logged_in_xxxx 的cookie,但是Wordpress就是不能实现这个cookie,调用 is_user_logged_in() 也是返回false。

经过我各种跟踪调试,最终定位到内核文件 wp-includes/default-constants.php 中的一个常量 COOKIEHASH 是罪魁祸首。

源代码如下:

define( ‘COOKIEHASH‘, md5( $siteurl ) );  

先提供解决方案,再讲原理

将 $siteurl 改成你的顶级域名字符串,即

define( ‘COOKIEHASH‘, md5( ‘example.com‘ ) ); 

这下整个世界都清爽了,cookie们终于愉快的在同一个域下同步了!

原理解释

为什么一个简单的常量会导致cookie同步失败呢?我们来逐层的恢复这个递归。

下面的这些函数并不是定义在同一个文件中,这里为了逻辑清晰将它们列在一起。

define( ‘COOKIEHASH‘, md5( $siteurl ) );
...
define(‘LOGGED_IN_COOKIE‘, ‘wordpress_logged_in_‘ . COOKIEHASH);
...
wp_parse_auth_cookie($cookie=‘‘, $scheme=‘‘);
//该函数返回根据 $scheme 读取 $_COOKIE 中的内容并返回结果,
//这里的 $scheme 是常量 "logged_in",函数内部使用 switch
//将 "logged_in" map 到了 LOGGED_IN_COOKIE 这个常量
...
wp_validate_auth_cookie($cookie, $scheme)
//根据上面的函数返回的结果,进一步判断cookie是否有效,并返回 user_id
...
add_filter( ‘determine_current_user‘, ‘wp_validate_auth_cookie‘,1);
//定义了一个filter,当apply的时候执行上述函数
...
get_currentuserinfo()
//这是很常用的一个内部函数,在这个函数里apply了上述filter
...
wp_get_current_user、is_user_logged_in等
//这些函数都调用了上述函数

分析到这里整个Wordpress的cookie解析流程也清晰了,问题很好定位,就是因为网站A 和 网站B 的 $siteurl 不同,导致常量定义不同,导致读不到cookie,最终导致了cookie不能跨子域共用。

以上。

转自:http://www.tuicool.com/articles/bUbqem

时间: 2024-08-06 16:34:13

黄聪:Wordpress二级域名共享用户cookie出现错误解决方案及WP的Cookie机制的相关文章

PHP实现同服务器多个二级域名共享 SESSION

现在很多分类信息网站都会分出很多个二级域名出来,比如:sh.ganji.com(上海赶集网), su.ganji.com(苏州赶集网)等等,像这种拥有多个二级域名的网站,该如何实现同步共享session呢,这里不讨论在多个服务器上的问题,仅仅分享一下在同一个服务器上面的多个二级域名网站如何共享session. 说这个问题之前,先来了解一下 PHP SESSION 的工作原理.在客户端(如浏览器)登录网站时,被访问的 PHP 页面可以使用 session_start() 打开 SESSION,这样

tomcat 二级域名 session共享

Tomcat下,不同的二级域名之间或根域与子域之间,Session默认是不共享的,因为Cookie名称为JSESSIONID的Cookie根域是默认是没设置 的,访问不同的二级域名,其Cookie就重新生成,而session就是根据这个Cookie来生成的,所以在不同的二级域名下生成的Session也 不一样.找到了其原因,就可根据这个原因对Tomcat在生成Session时进行相应的修改(注:本文针对Tomcat 6.0.18). 修改tomcat源代码 包:catalina.jar 类:or

到底二级域名和一级域名哪个更利于SEO

到底二级域名和一级域名哪个更利于SEO呢?本文是从百度官方转载详细的介绍:二级域名和一级域名的区别,请各位认真阅读. 二级域名和子域名的区别可以通过以下3点来解读: 一,二级域名的特点 搜索引擎往往将二级域名当作一个独立的网站看待,同时会视情况将主域名的评价传递一部分给二级域名.使用二级域名会使同domain下站点变多,但是每个站点的体量变小. 二级域名的SEO特点是: 1,二级域名对用户来说也是一个完整的域名,显得更有权威性 2,二级域名网页之间相关性更强,对于搜索引擎来说主题更集中 3,相较

asp.net forms 表单验证 实现跨域共享cookie(即SSO,单点登录(在二级域名下))

1.前提: 需要做一个单点登录,使用asp.net自带的表单验证(FormsAuthentication) 配置文件怎么写,如下(基本的): <authentication mode="Forms"> <forms loginUrl="~/user/login" enableCrossAppRedirects="true" timeout="3600" name="qz.bbs" cook

黄聪:WordPress 多站点建站教程(二):后台(管理网络)设置详解,如何管理子站的用户、主题、插件、设置等功能

建立好了子站,我们需要有个地方配置所有子站的主题.插件等功能,我们可以在后台看到 我的站点--管理网络 如下图: 在 管理网络--仪表盘 里面,我们可以创新用户和站点,也提供了查询功能. 要注意的是:当你新上传的主题或者插件,都需要在管理网络那边的主题和插件里面将你上传的主题和插件开启.这样才可以在你的子站点中查看的到. 黄聪:WordPress 多站点建站教程(二):后台(管理网络)设置详解,如何管理子站的用户.主题.插件.设置等功能

在ExpressJS中设置二级域名跨域共享Cookie

问题:我使用expressjs和mongostore来管理session.下面是expressjs中的设置. app.configure(function(){ app.use(express.session({ secret: conf.secret, maxAge: new Date(Date.now() + 3600000), cookie: { path: ‘/‘ }, store: new MongoStore(conf.db) })); }); 我已经在上面设置了cookie路径.但

二级域名session 共享方案

二级域名session 共享方案 1.利用COOKIE存放session_id(); 实例: 域名一文件php代码: <?php session_start(); setcookie("session_id",session_id(),time()+3600*24*365*10,"/",".session.com"); $_SESSION['user_name'] = '梁山良民'; echo $_SESSION['user_name'];

ASP.NET二级域名站点共享Session状态

前面一篇文章提到了如何在使用了ASP.NET form authentication的二级站点之间共享登陆状态, http://www.cnblogs.com/jzywh/archive/2007/09/23/902905.html, 今天, 我要写的是如何在二级域名站点之间,主站点和二级域名站点之间共享Session. 首先, Session要共享,站点之间SessionID必须要一致,那怎么保证SessionID一致呢? ASP.NET中的SessionID是存储在客户端的cookie之中键

黄聪:WordPress 多站点建站教程(六):使用WP_Query、switch_to_blog函数实现获取子站点分类中的文章

首先在你使用主题的funtions.php里面添加下代码: //根据时间显示最新的分类文章内容,每个站点显示一篇内容 //$blog_id 子站点ID //$catid 分类ID wp_reset_query(); switch_to_blog($blog_id); global $post;?> $my_query2 = new WP_Query('showposts=1&order=desc&orderby=date&cat='.$catid); while ($my_q