WordPress DiscourseConnect 客户端 - 过期 nonce

我遇到了同样的问题,使用 Google 登录时也会出现。在 WordPress 之前,我们使用 Nginx 作为反向代理。这会有关联吗?

我猜想这发生在通过 Discourse 站点登录 WordPress 时。如果是这种情况,问题在于 WordPress 生成的 nonce 已过期。这在启用了对象缓存的 WordPress 网站上会发生。

一种解决方案是在所有包含“使用 Discourse 登录”链接的页面上禁用对象缓存。对于这种方法,请确保为匿名用户禁用对象缓存。

另一个解决方案在此处概述:Wordpress SSO Expired nonce - #15 by simon WordPress 主题的 functions.php 文件中。

该函数会将一个随机字符串添加到“使用 Discourse 登录”URL。该随机字符串会触发 WordPress 破坏缓存并为用户生成一个新的 nonce。@angus,这可能应该添加到插件的代码中:wp-discourse/lib/sso-client/sso-client-base.php at main · discourse/wp-discourse · GitHub nonce 而不是为每次访问生成新 nonce 的问题。

3 个赞

非常感谢您的回复。一旦我们将 Discourse 投入实际运行,我们将尝试禁用 WordPress 网站上的 Nging 缓存,如果无效,我们将按照说明编辑 functions.php。

谢谢 @simon

我不太清楚为什么这会清除 WordPress 的对象缓存,因为通常将随机字符串添加到 URL 是为了避免浏览器缓存。WordPress 的对象缓存中缓存了哪个查询?我看到该方法可能有效的非对象缓存原因

但是,如果是这种情况,我们可能需要进行一些细微的调整。但我可能遗漏了什么?

据我所知,问题不在于 WordPress 对象缓存,因为它在请求之间不是持久的。问题发生在具有某种持久缓存的网站上:https://developer.wordpress.org/reference/classes/wp_object_cache/#persistent-caching。这可以通过插件进行配置,但一些托管提供商(例如 WP Engine)也默认启用了它。我认为对于 WP Engine 的情况,他们不在其登录页面上启用对象缓存,但会在所有其他页面上为匿名用户启用它。因此,在 WP Engine 上,只有当“使用 Discourse 登录”链接添加到登录页面以外的页面时,才会触发此问题。

discourse_sso_url 的问题在于,当它始终设置为相同值时,对于启用了持久缓存的网站,它将始终返回相同的 nonce。将其 discourse_sso 值设置为随机字符串,而不是默认值 1,会破坏缓存。至少在我以前测试时一直如此。我现在没有配置来测试它。

编辑:这里有更多关于该问题的细节:https://meta.discourse.org/t/discourse-as-provider-wp-sso-nonce-error/117113/14。我查看这个问题已经有一段时间了。当时解决该问题的方法似乎是 同时discourse_sso_url 中添加一个随机字符串,并确保登录链接显示的页面未启用页面缓存(否则,对于匿名用户的每次访问,随机字符串将不是唯一的)。

明白了。感谢您的解释。

我认为我们应该一步一步来,因为我担心在这里推送一个修复程序而不确定它是否会是“多元化”的,也就是说,它将与不同的缓存方法一起工作。

我仍然不太清楚各种缓存在此特定问题中的作用,特别是持久对象缓存和页面缓存(如果存在)的不同作用。我可以看到页面缓存为什么会引起这个问题,但持久对象缓存(目前)不会。如果是后者,我们可能需要调整我们 Nonce 类中的查询。

下周我需要对此进行更深入的测试。

@Petr_Mišák 您能否先尝试禁用登录链接页面上的任何页面缓存,并告知我们您的进展?

我将尝试禁用 WordPress 网站上的 Nginx Microcache 来测试登录页面。我们通过 Discourse 登录 WordPress 的测试页面在这里:Test Discourse Login | Svět Androida

我(偶尔)注意到,如果我使用 Google 登录,就会出现问题。

但是现在令我惊讶的是,我们使用短代码放在页面上的 Discourse 登录链接已从我们的测试页面消失了。

有人知道为什么会这样吗?

在我解决测试登录页面的问题之前,我没有“过期的 nonce”来测试它。

请先确保没有某种缓存问题。让我们知道您的进展。

我明白了,我们会一步一步解决,我同意。

错误似乎也发生在官方登录时。这是用于模拟它的电子邮件,以便您可以自己尝试。

  1. 转到页面 Přihlásit se ‹ Svět Androida — WordPress
  2. 使用“使用 Discourse 登录”登录,并在那里使用您的 Google 帐户
  3. 使用 Discourse 登录后,您将被重定向回 https://www.svetandroida.cz/https://www.svetandroida.cz/wp-login.php 并显示错误消息,请参见屏幕截图。

测试不充分,因为问题并不总是出现。
请尝试一下,在我禁用 Nginx 缓存之前告诉我您是否收到错误。谢谢

1 个赞

我检查了我们的 Nginx Microcache 在 Přihlásit se ‹ Svět Androida — WordPress 的状态,但似乎那里根本没有使用 Nginx Microcache。因此,“过期随机数”问题将与其他问题有关。

1 个赞

@Petr_Mišák,只是想问一下你是否找到了罪魁祸首?

我们已经搜索过了,但到目前为止,不幸的是,没有成功。但我们将继续搜索并寻找问题的原因。

我相当确定通过 Discourse 登录 https://www.svetandroida.cz/ 时出现的问题与 nonce 被缓存有关。我测试此问题的方法是单击“使用 Discourse 登录”链接(https://www.svetandroida.cz/?discourse_sso=1&redirect_to=https%3A%2F%2Fwww.svetandroida.cz%2F)。

第一次单击时,我被重定向到 https://komunita.svetandroida.cz/,使用 Gmail 在 Discourse 网站上创建了一个帐户,然后作为已登录用户重定向回您的 WordPress 网站。

然后我注销了您的 WordPress 网站,并尝试通过再次单击“使用 Discourse 登录”链接重新登录。这次我收到了“nonce 已过期”的错误。

然后,我生成了一个登录链接,并在 discourse_sso URL 参数中设置了一个随机值,例如 https://www.svetandroida.cz/?discourse_sso=181253058&redirect_to=https%3A%2F%2Fwww.svetandroida.cz%2F,并且能够毫无问题地通过 Discourse 登录您的 WordPress 网站。

我已经尝试了几次,包括使用插件生成的登录链接(https://www.svetandroida.cz/?discourse_sso=1&redirect_to=https%3A%2F%2Fwww.svetandroida.cz%2F)和设置了随机值的 discourse_sso 参数的登录链接。似乎返回的 nonce 被缓存了至少几分钟。

在不完全调试问题的情况下,我相当确定您可以通过将以下内容添加到主题的 functions.php 文件中来解决问题(它会将一个随机字符串设置为 discourse_sso URL 参数。只要您的登录页面没有启用“页面缓存”,这应该就可以正常工作。)

add_filter('wpdc_sso_client_query', 'wpdc_custom_sso_client_query' );
function wpdc_custom_sso_client_query() {
    return wp_generate_password( 12, false );
}

如果您确实想调试这个问题,以下是我看到的成功请求。请注意 Cache-Svetzitrka: STALE 行。这可能表明存在自定义缓存层,并且缓存对于成功请求是 STALE(因此生成了一个新的 nonce)。

摘要
Request URL:
https://www.svetandroida.cz/?discourse_sso=1&redirect_to=https%3A%2F%2Fwww.svetandroida.cz%2F
Request Method:
GET
Status Code:
302 Found
Remote Address:
93.185.102.156:443
Referrer Policy:
strict-origin-when-cross-origin
Cache-Control:
max-age=0
Cache-Svetzitrka:
STALE
Content-Length:
0
Content-Type:
text/html; charset=UTF-8
Date:
Mon, 11 Dec 2023 09:38:05 GMT
Expires:
Mon, 11 Dec 2023 09:21:47 GMT
Location:
https://komunita.svetandroida.cz/session/sso_provider?sso=bm9uY2U9MGU3NTNjYWNhNjMwNmMzNzM5M2MyODk4MjZlYzMxMjQmcmV0dXJuX3Nzb191cmw9aHR0cHMlM0ElMkYlMkZ3d3cuc3ZldGFuZHJvaWRhLmN6JTJG&sig=32ddcc85bd2dd7175f963e791cc9ac734a607355d773422d3abec6173c9f656b
Server:
nginx
Strict-Transport-Security:
max-age=10886400; includeSubdomains; preload
X-Content-Type-Options:
nosniff
X-Frame-Options:
SAMEORIGIN
X-Redirect-By:
WordPress

以下是我看到的失败请求。Cache-Control: no-cache, no-store 行似乎表明响应 不应该 被缓存,但响应中的 from service worker 条目表明响应可能来自 service worker 的缓存。

摘要
Request URL:
https://www.svetandroida.cz/?discourse_sso=1&redirect_to=https%3A%2F%2Fwww.svetandroida.cz%2F
Request Method:
GET
Status Code:
302 Found (from service worker)
Referrer Policy:
strict-origin-when-cross-origin
Cache-Control:
no-cache, no-store
Content-Security-Policy:
upgrade-insecure-requests; base-uri 'self'; object-src 'none'; script-src https://komunita.svetandroida.cz/logs/ https://komunita.svetandroida.cz/sidekiq/ https://komunita.svetandroida.cz/mini-profiler-resources/ https://komunita.svetandroida.cz/assets/ https://komunita.svetandroida.cz/extra-locales/ https://komunita.svetandroida.cz/highlight-js/ https://komunita.svetandroida.cz/javascripts/ https://komunita.svetandroida.cz/plugins/ https://komunita.svetandroida.cz/theme-javascripts/ https://komunita.svetandroida.cz/svg-sprite/ https://www.google-analytics.com/analytics.js https://www.googletagmanager.com/gtag/js 'sha256-8uAKDaK4QxxCeYZl0Wxad2Nnj2tgKyA14hYBh66pnn0='; worker-src 'self' https://komunita.svetandroida.cz/assets/ https://komunita.svetandroida.cz/javascripts/ https://komunita.svetandroida.cz/plugins/; frame-ancestors 'self'; manifest-src 'self'
Content-Type:
text/html; charset=utf-8
Date:
Mon, 11 Dec 2023 09:38:05 GMT
Discourse-Logged-Out:
1
Location:
https://komunita.svetandroida.cz/login
Referrer-Policy:
strict-origin-when-cross-origin
Server:
nginx
Set-Cookie:
sso_payload=sso%3Dbm9uY2U9MGU3NTNjYWNhNjMwNmMzNzM5M2MyODk4MjZlYzMxMjQmcmV0dXJuX3Nzb191cmw9aHR0cHMlM0ElMkYlMkZ3d3cuc3ZldGFuZHJvaWRhLmN6JTJG&sig=32ddcc85bd2dd7175f963e791cc9ac734a607355d773422d3abec6173c9f656b; path=/; SameSite=Lax
Set-Cookie:
_forum_session=kGW2K6gafsjS90qQMEmxzjggEYo4tZPZe76XZNVro34ilyuuHsaYt2nEzC9h6tfiSBmY9XoDdxh1SV3S8n%2BwqrbsD58UvJBz6khjm%2Fty83ufkgry8daHDdyoTfFwQOjAbXrWeGIwkS4edGY1XetNwXhu%2FNJUghqmq8BEUycBt7098KUO%2BmRYDl5iSL0FNhUzo5Hc7xwRg0tfxuxmb%2FIyVLnbFz6IJuGB3Y95PRcU5DYIwAAny1GQbKQ23kSjgALxAThG7aA%2B7LCI9cJNWV1JRSy%2FTElDN3iugKuVpaQcrSPhV3SvQaiNH3MCfLwu6yxlp%2BZ%2BwTyw22czX8bb197z36WhlbghYtxvKYGRjONJQUagisjPpMrCAcGeTKsGB4JgnUKCtlrwIoFvaDxjec7hMo3aCnibbbkmcxWc6LvD6G2xaxkDgebe7RpvfTYdG8cn8j6rNwX3hM8la4RqZnmma0%2FQlSrfj0BjfY7lnan6TYm28vLwH%2FFfdZoRbo6JdTs5AFjCJvx9UXSjFmoXHH1R1yfAizPeKDFnpiuUs4a%2FBzWafQ%3D%3D--8PEvbWwpqBuJMSRJ--CzzhBea4mmv58a7KLEnukw%3D%3D; path=/; secure; HttpOnly; SameSite=Lax
Set-Cookie:
_t=; path=/; max-age=0; expires=Thu, 01 Jan 1970 00:00:00 GMT; SameSite=Lax
Strict-Transport-Security:
max-age=31536000
Vary:
Accept
X-Content-Type-Options:
nosniff
X-Discourse-Route:
session/sso_provider
X-Download-Options:
noopen
X-Frame-Options:
SAMEORIGIN
X-Permitted-Cross-Domain-Policies:
none
X-Request-Id:
001750b9-94f2-4bf0-8503-9d673463b91e
X-Runtime:
0.012335
X-Xss-Protection:
0
2 个赞