多实例WordPress使用Memcached处理会话请求每次请求由不同的服务器处理时登录

时间:2020-11-23 作者:JesusIniesta

我的网站使用BuddyPress提供社交网络功能。我还有一个memcached服务器,可供网站的所有部署访问,PHP会话处理程序设置为memcached,并具有适当的路径。

尽管有这种设置,我认为应该允许登录的用户与任何部署对话,而无需再次登录,只要服务器发生更改,用户就会重定向到登录页面。

粘滞会话不是一个选项,因为我希望具有自动伸缩性以及推出新部署的选项,这将受到粘滞会话的影响。

Edit: Adding PHP Info session related values

| **Directive**                     |  **Local Value**  |   **Master Value** |
| session.name                      |  PHPSESSID    |   PHPSESSID |
| session.referer_check             |  no value     |   no value |
| session.save_handler              |  memcached    |   memcached |
| session.save_path                 |  <path_tested_with_w3tc>:11211    |   <path_tested_with_w3tc>:11211 |
| session.serialize_handler         |  php  |   php |
| session.sid_bits_per_character    |  4    |   4  |
| session.sid_length                |  32   |   32 |
| session.upload_progress.cleanup   |  On   |   On |
| session.upload_progress.enabled   |  On   |   On |
| session.upload_progress.freq      |  1%   |   1% |
| session.upload_progress.min_freq  |  1    |   1  |
| session.upload_progress.name      |  PHP_SESSION_UPLOAD_PROGRESS  |   PHP_SESSION_UPLOAD_PROGRESS |
| session.upload_progress.prefix    |  upload_progress_ |   upload_progress_ |
| session.use_cookies               |  1    |   1 |
| session.use_only_cookies          |  1    |   1 |
| session.use_strict_mode           |  0    |   0 |
| session.use_trans_sid             |  0    |   0 |

Cookies generated after login:

set-cookie: wordpress_sec_b58b81a6569307dbe35afffdec99a12b=SECRET%7C1606311709%7CW9rYFhxdPDZXsn0eEAsTgQjAYUz5JS9mW3i8vZasqNY%7Cf272d224acddd83e4b5325619a84ab9c6b0a8e164bab70d02fd8d2988be5ae8a; path=/wp-content/plugins; secure; HttpOnly
set-cookie: wordpress_sec_b58b81a6569307dbe35afffdec99a12b=SECRET%7C1606311709%7CW9rYFhxdPDZXsn0eEAsTgQjAYUz5JS9mW3i8vZasqNY%7Cf272d224acddd83e4b5325619a84ab9c6b0a8e164bab70d02fd8d2988be5ae8a; path=/wp-admin; secure; HttpOnly
set-cookie: wordpress_logged_in_b58b81a6569307dbe35afffdec99a12b=SECRET%7C1606311709%7CW9rYFhxdPDZXsn0eEAsTgQjAYUz5JS9mW3i8vZasqNY%7Cc62acb99725ffe6017e887ba7f380a3658cbcc22f1194a40d70edbb409f4063f; path=/; secure; HttpOnly
set-cookie: wordpress_user_sw_b58b81a6569307dbe35afffdec99a12b=%20; expires=Sun, 24-Nov-2019 13:41:49 GMT; Max-Age=0; path=/
set-cookie: wordpress_user_sw_secure_b58b81a6569307dbe35afffdec99a12b=%20; expires=Sun, 24-Nov-2019 13:41:49 GMT; Max-Age=0; path=/
set-cookie: wordpress_user_sw_olduser_b58b81a6569307dbe35afffdec99a12b=%20; expires=Sun, 24-Nov-2019 13:41:49 GMT; Max-Age=0; path=/
set-cookie: po_assigned_roles[0]=administrator; path=/
set-cookie: po_assigned_roles[1]=community_member; path=/
set-cookie: po_assigned_roles[2]=tpc_team_member; path=/
set-cookie: po_assigned_roles[3]=bbp_keymaster; path=/
set-cookie: po_assigned_roles[4]=collective_member; path=/

Cookies sent to NEW instance:

cookie: 
    __cfduid=d0173c09618ab13e2c6b4fb6ba43057ff1606138743; 
    dwqa_anonymous=ftswkkbhNkZwV07Xhv6uO1IdoLqLkNmIShN9OsDEzHQ; 
    Pastease.passive.chance.yJUaALuUqv6jdyG=chance6.9; 
    Pastease.passive.activated.yJUaALuUqv6jdyG=0; 
    _ga=GA1.2.2022121795.1606138752; 
    _gid=GA1.2.558054667.1606138752; 
    _fbp=fb.1.1606138752341.26687996; 
    _hjTLDTest=1; 
    _hjid=9d9690df-9108-4e17-8814-7cee6ca9a482; 
    _hjFirstSeen=1; 
    __hstc=114933784.830ff540ba6bdbe7807f9f22ababe3ea.1606138753838.1606138753838.1606138753838.1; 
    hubspotutk=830ff540ba6bdbe7807f9f22ababe3ea; 
    __hssrc=1; 
    wordpress_logged_in_b58b81a6569307dbe35afffdec99a12b=SECRET%7C1606311709%7CW9rYFhxdPDZXsn0eEAsTgQjAYUz5JS9mW3i8vZasqNY%7Cc62acb99725ffe6017e887ba7f380a3658cbcc22f1194a40d70edbb409f4063f; 
    po_assigned_roles[0]=administrator; 
    po_assigned_roles[1]=community_member; 
    po_assigned_roles[2]=tpc_team_member; 
    po_assigned_roles[3]=bbp_keymaster; 
    po_assigned_roles[4]=collective_member; 
    po_assigned_roles[5]=tpc_employee; 
    __hssc=114933784.2.1606138753838; 
    route=fea005034f6d3f0ec569ed6fc070f1a3

Full response headers from NEW instance

cache-control: s-max-age=604800, s-maxage=604800, max-age=60
cf-apo-via: origin,host
cf-cache-status: MISS
cf-edge-cache: cache,platform=wordpress
cf-ray: 5f6b613c3cfb1501-MAD
cf-request-id: 0696fb19a10000150178b9a000000001
content-encoding: br
content-type: text/html; charset=UTF-8
date: Mon, 23 Nov 2020 13:54:06 GMT
expect-ct: max-age=604800, report-uri="https://report-uri.cloudflare.com/cdn-cgi/beacon/expect-ct"
link: <https://gtest.portfolio-collective.com/wp-json/>; rel="https://api.w.org/", <https://gtest.portfolio-collective.com/wp-json/wp/v2/pages/644>; rel="alternate"; type="application/json", <https://gtest.portfolio-collective.com/>; rel=shortlink
nel: {"report_to":"cf-nel","max_age":604800}
referrer-policy: no-referrer-when-downgrade
report-to: {"endpoints":[{"url":"https:\\/\\/a.nel.cloudflare.com\\/report?s=0E3P639p9hpt6%2BSo1PdNJAhIG3P2%2Bvr8AckTijZs%2FEdTxNZzQv9UbzT6Qbx0Fv603GiFw5yUSeryKwmiRps%2FjjvU0isDb9pOBBNls4S2PVwSHcFwscqhDUGwsqiD25s%3D"}],"group":"cf-nel","max_age":604800}
server: cloudflare
strict-transport-security: max-age=15724800; includeSubDomains
vary: Accept-Encoding
x-powered-by: PHP/7.4.12
x-wp-cf-super-cache: cache
x-wp-cf-super-cache-active: 1
x-wp-cf-super-cache-cache-control: s-max-age=604800, s-maxage=604800, max-age=60

Response from NEW instance after logging in

Cookie ID和用户保持不变,过期和哈希更改

cache-control: private, no-cache, no-store, max-age=0, must-revalidate, proxy-revalidate
cf-cache-status: DYNAMIC
cf-edge-cache: cache,platform=wordpress
cf-ray: 5f6b61a66edc1501-MAD
cf-request-id: 0696fb5c0600001501ea1a3000000001
content-type: text/html; charset=UTF-8
date: Mon, 23 Nov 2020 13:54:20 GMT
expect-ct: max-age=604800, report-uri="https://report-uri.cloudflare.com/cdn-cgi/beacon/expect-ct"
expires: Fri, 01 Jan 2016 00:00:01 GMT
location: /collective/activity/
nel: {"report_to":"cf-nel","max_age":604800}
pragma: no-cache
referrer-policy: no-referrer-when-downgrade
report-to: {"endpoints":[{"url":"https:\\/\\/a.nel.cloudflare.com\\/report?s=7BldsEXB3EH36f6PSIrr7%2FLHpPgTmxAVVHfPsRUoSUvvRzY1%2B1n8SivJ0vFcuG5z%2FG3mpVizYrx5NP6UNJASzV6dqynFtvaP%2BYdsRih5inN4kiXedgrL%2BSXajtWFAgQ%3D"}],"group":"cf-nel","max_age":604800}
server: cloudflare
set-cookie: wordpress_sec_b58b81a6569307dbe35afffdec99a12b=SECRET%7C1606312459%7CC8XCWWQqr6b3YBGLwTuxfzrjP70NdIGAEuVHMaSNmvG%7C852115cba50a2f5d729857a9b9b0379c5e269c0f2bcd7e21c022ff0088e4a0d3; path=/wp-content/plugins; secure; HttpOnly
set-cookie: wordpress_sec_b58b81a6569307dbe35afffdec99a12b=SECRET%7C1606312459%7CC8XCWWQqr6b3YBGLwTuxfzrjP70NdIGAEuVHMaSNmvG%7C852115cba50a2f5d729857a9b9b0379c5e269c0f2bcd7e21c022ff0088e4a0d3; path=/wp-admin; secure; HttpOnly
set-cookie: wordpress_logged_in_b58b81a6569307dbe35afffdec99a12b=SECRET%7C1606312459%7CC8XCWWQqr6b3YBGLwTuxfzrjP70NdIGAEuVHMaSNmvG%7C2302e8cf7d25c4b1e6f9d5e665890e2e5b85c2e938dd3194123f374fd0f85144; path=/; secure; HttpOnly
set-cookie: wordpress_user_sw_b58b81a6569307dbe35afffdec99a12b=%20; expires=Sun, 24-Nov-2019 13:54:19 GMT; Max-Age=0; path=/
set-cookie: wordpress_user_sw_secure_b58b81a6569307dbe35afffdec99a12b=%20; expires=Sun, 24-Nov-2019 13:54:19 GMT; Max-Age=0; path=/
set-cookie: wordpress_user_sw_olduser_b58b81a6569307dbe35afffdec99a12b=%20; expires=Sun, 24-Nov-2019 13:54:19 GMT; Max-Age=0; path=/
set-cookie: po_assigned_roles[0]=administrator; path=/
set-cookie: po_assigned_roles[1]=community_member; path=/
set-cookie: po_assigned_roles[2]=tpc_team_member; path=/
set-cookie: po_assigned_roles[3]=bbp_keymaster; path=/
set-cookie: po_assigned_roles[4]=collective_member; path=/
set-cookie: po_assigned_roles[5]=tpc_employee; path=/
strict-transport-security: max-age=15724800; includeSubDomains
x-powered-by: PHP/7.4.12
x-redirect-by: WordPress

1 个回复
最合适的回答,由SO网友:JesusIniesta 整理而成

The problem was that my *_KEY tokens were being generated each time Kubernetes was creating a new instance, as @Rup and @Tom-J-Nowel rightly pointed.

因为我的docker形象是从wp-config.php 包含模板,以便由official wordpress docker image 我很难看出这是一个变量。在按照我得到的建议反复检查之后,我意识到在每种情况下都是不同的。

因此,解决方案非常简单,只要确保以下变量的值在所有实例中都相同:

define( \'AUTH_KEY\',         \'<auth_key_token>\');
define( \'SECURE_AUTH_KEY\',  \'<secure_auth_key_token>\');
define( \'LOGGED_IN_KEY\',    \'<logged_in_key_token>\');
define( \'NONCE_KEY\',        \'<nonce_key_token>\');
define( \'AUTH_SALT\',        \'<auth_salt_token>\');
define( \'SECURE_AUTH_SALT\', \'<secure_auth_salt_token>\');
define( \'LOGGED_IN_SALT\',   \'<logged_in_salt_token>\');
define( \'NONCE_SALT\',       \'<nonce_salt_token>\');
在我的kubernetes对象中是这样的:

apiVersion: apps/v1
kind: Deployment
metadata:
  namespace: k8s-web
spec:
  replicas: 1
  selector:
    matchLabels:
      app: k8s-web
  template:
    metadata:
      labels:
        app: k8s-web
    spec:
      containers:
        - image: wordpress:php7.4-apache
          name: web-container
          env:
            - name: WORDPRESS_DB_HOST
              value: <wordpress_db_host>
            - name: WORDPRESS_DB_NAME
              value: <wordpress_db_name>
            - name: WORDPRESS_DB_USER
              value: <wordpress_db_user>
            - name: WORDPRESS_DB_PASSWORD
              value: <wordpress_db_password>
            - name: WORDPRESS_TABLE_PREFIX
              value: <wordpress_table_prefix>
            - name: WORDPRESS_AUTH_KEY
              value: <wordpress_auth_key>
            - name: WORDPRESS_AUTH_SALT
              value: <wordpress_auth_salt>
            - name: WORDPRESS_SECURE_AUTH_KEY
              value: <wordpress_secure_auth_key>
            - name: WORDPRESS_SECURE_AUTH_SALT
              value: <wordpress_secure_auth_salt>
            - name: WORDPRESS_LOGGED_IN_KEY
              value: <wordpress_logged_in_key>
            - name: WORDPRESS_LOGGED_IN_SALT
              value: <wordpress_logged_in_salt>
            - name: WORDPRESS_NONCE_KEY
              value: <wordpress_nonce_key>
            - name: WORDPRESS_NONCE_SALT
              value: <wordpress_nonce_salt>

相关推荐

Large Session Tokens

我们在共享服务器上有一个Wordpress站点,最近由于磁盘空间不足而崩溃,因为我们的MySQL二进制日志在几分钟内就填满了驱动器。在查看了其中的内容后,我们追踪到该站点中的一个用户,该用户在usermeta 元键为的表session_tokens. 我为该用户单击了“随处注销”选项,删除了这些记录,但今天同样的问题开始出现,他的所有令牌都回来了。有什么想法吗?我真的不知道从哪里开始,也不知道他是如何积累了这么多代币的。我写了一个Wordpress计划的任务,应该每小时删除过期的门票,但由于他的帐户什么都