在若干年以前,我刚开始折腾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

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

  1. 顶级域名和二级域名共享cookie及相互删除cookie

    在CSDN看到一个cookie设置domain时,如何删除的问题, 自己也只知道domain设置为顶级域名时可以被其他二级域名共享,但是如何删除还是有一点搞不清楚,所以特意测试了下cookie和dom ...

  2. asp.net基于StateServer的二级域名共享session

    备注:亲自试验有效,如果网友有通过下面的教程未实现session共享的,欢迎留言说明你遇到的问题.必有回复. 最近为实现的二级域名共享session纠结好久.网上的很多实现的方法试了都不行,查了很久才 ...

  3. .NET二级域名共享Session

    ASP.NET二级域名站点共享Session状态 今天, 我要写的是如何在二级域名站点之间,主站点和二级域名站点之间共享Session. 首先, Session要共享,站点之间SessionID必须要 ...

  4. 设置二级域名共享一级域名Cookie和删除共享Cookie

     设置共享Cookie: 二级域名要想共享一级域名的cookie,只需要设置cookie.Domain = ".一级域名.com";   删除共享Cookie:  HttpCook ...

  5. PHP实现同服务器多个二级域名共享 SESSion

    现在很多分类信息网站都会分出很多个二级域名出来,比如:sh.ganji.com(上海赶集网), su.ganji.com(苏州赶集网)等等,像这种拥有多个二级域名的网站,该如何实现同步共享sessio ...

  6. Froms 认证 二级域名共享session登录凭证

    1. 需要共享的web.config 里需要加添 <authentication mode="Forms"> <forms name="/> &l ...

  7. 黄聪:iis7.5 偶尔出现500服务器错误-内部服力器错误

    搞了半天,发现是PHP映射模块出错了,最新的PHP7处理模块不行,换成5.6的就好了

  8. 黄聪:Mysql开启InnoDB引擎出现1067错误的解决办法

    在my.ini文件添加下面这行: innodb_force_recovery = 1 可以解决:InnoDB: Attempted to open a previously opened tables ...

  9. WordPress 设置GeoIP数据库目录权限时错误解决方案

    存在一个问题 更新完WP-statistics后,不知道为什么出现了一个错误提示:设置GeoIP数据库目录权限时错误,请确保您的Web服务器有权限写入到目录/var/www/html/wordpres ...

随机推荐

  1. Python中 filter | map | reduce | lambda的用法

      1.filter(function, sequence):对sequence中的item依次执行function(item),将执行结果为True的item组成一个List/String/Tupl ...

  2. 自己封装的一个java图片验证码

    验证码生成器: package com.lz.Tools; import java.awt.Color; import java.awt.Font; import java.awt.Graphics; ...

  3. 美女程序员是如何将QQ转换成题目中那串数字的--读博文《找女神要QQ号码》

    我只能说好好的端午节你们不约么?,还在这里写代码?我也是够无聊的,下班了不走也在这跟风写着玩!<找女生要QQ号码原文>原文链接http://www.cnblogs.com/iforever ...

  4. 云端 Linux下安装 Java

    根据需要在给云端的机器安装Java 问题的分解为2个一个是Java源文件的传输.一个是Linux下Java的安装. Java 传输到云端: 可以通过SSH Secure File Transfer C ...

  5. OC语言前期准备

    OC语言前期准备 一.OC简介 Oc语言在c语言的基础上,增加了一层最小的面向对象语法,完全兼容C语言,在OC代码中,可以混用c,甚至是c++代码. 可以使用OC开发mac osx平台和ios平台的应 ...

  6. Selenium - CSS Selector

    Selenium - CSS Selector http://www.cnblogs.com/bugua/archive/2012/08/16/2641647.html   昨天我练习了用CSS(即层 ...

  7. ubuntu 14.04 下找不到命令,路径出错

    在安装一些东西时,可能操作上不小心把路径覆盖或打错,造成一些基本命令如ls mkdir等无法使用,就会出现以下提示错误. 错误: 由于/usr/bin 不在PATH 环境变量中,故无法找到该命令 根本 ...

  8. ASP.NET使用Razor语法无法正确识别.cshtml文件

    ASP.NET使用WebPage编程的好处之一是可以使用强大的Razor语法, 但初次使用Razor语法会碰到一个比较头疼的问题就是无法直接写一个.cshtml让浏览器去识别,查资料也没有找到相关问题 ...

  9. Rhel6-pacemaker+drbd配置文档

    系统环境: rhel6 x86_64 iptables and selinux disabled 主机: 192.168.122.119 server19.example.com 192.168.12 ...

  10. HDU1004 BALLO0N

    Let the Balloon Rise Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others ...