# Tecnoblog 使用 Discourse 评论系统的体验

**URL:** <https://meta.discourse.org/t/tecnoblogs-experience-with-discourse-comments/400721>\
**Category:** Feature\
**Tags:** embedding\
**Created:** [2026年四月15日 18:15 UTC](https://meta.discourse.org/t/tecnoblogs-experience-with-discourse-comments/400721 "2026-04-15T18:15:07Z")\
**Posts on this page:** 1\
**Showing post:** 55

<div class="post-metadata">

**Author:** ![Falco](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/falco/32/179432_2.png) [@Falco](https://meta.discourse.org/u/Falco)\
**Post date:** [2026年五月15日 17:09 UTC](https://meta.discourse.org/t/tecnoblogs-experience-with-discourse-comments/400721/55 "2026-05-15T17:09:29Z")

</div>

> [@Thiago\_Mobilon](#):
>
> ### **5. 登录摩擦**
> 
> 当前的流程有点像是转化率的杀手：用户点击登录 → 打开新标签页 → 完成登录 → 用户停留在社区主页。回到博客文章页面，iframe 仍然显示未登录状态，直到用户手动刷新整个页面。这是一个令人困惑的循环，导致人们在评论前放弃并离开。
> 
> 自从启用新的嵌入功能后，我们的 **每日注册量翻了一番以上** ，这很好。然而，我们的参与度指标没有任何变化。事实上，我们的 **DAU/MAU 下降了** ——我们有更多登录用户，但他们并没有互动。像“每日活跃用户”、“新贡献者”和“发帖数”等指标都没有任何增长。
> 
> 这证明人们_想要_参与讨论，但他们在登录循环中迷失了方向，在能够实际评论之前就放弃了帖子。

这个问题现在已经修复，请更新以获取新的登录流程。

> <https://github.com/discourse/discourse/pull/39756>
>
> Previously, full app embeds loaded on a third-party domain could not see the for…um's session cookie, leaving users effectively logged out, and \`showLogin\` only opened a dead-end \`/login\` tab the iframe never reacted to.
> 
> This adds an \`embed\_full\_app\_signin\_flow\` site setting (on by default, gated to full app embed mode) that intercepts logged-out actions inside the iframe with a guided flow: bridge storage access if the iframe's cookie jar is partitioned, then either reload (if the user is already signed in elsewhere) or open a top-level sign-in tab and watch the session via polling.
> 
> \## Flow
> 
> 1. User clicks an auth-gated action (Reply CTA, Like, etc.). \`showLogin\` / \`showCreateAccount\` and the embed-topic-footer reply CTA route into the new \`embed-auth-flow\` service.
> 2. \*\*If \`document.hasStorageAccess()\` is \`false\`\*\* — Safari ITP, Firefox Total Cookie Protection, Chrome's 3p cookie phaseout — an in-iframe modal asks the user to share their session. Confirming calls \`requestStorageAccess()\` (synchronously inside the click handler so user activation is preserved).
> 3. Once we have access, the service probes \`/session/current.json\`. If the user is already signed in elsewhere (common Firefox ETP scenario), the iframe reloads to pick up the session — no popup.
> 4. Otherwise, a sign-in modal opens a top-level \`/login?embed\_signin\_callback=1\` (or \`/signup\`) tab and shows a waiting state with a spinner. The iframe polls \`/session/current.json\` every 3s for up to 5 min.
> 5. When polling sees a logged-in response, the iframe reloads. The popup self-closes once it has a session, driven by the \`embed\_signin\_callback\` query param + sessionStorage flag.
> 
> \## Why polling instead of \`postMessage\`
> 
> The popup-side callback originally posted a success message back to the opener. Discourse's default \`Cross-Origin-Opener-Policy\` (\`same-origin-allow-popups\`) typically mismatches an embedding host's (\`unsafe-none\`), which severs \`window.opener\` on the popup's very first load — and any OAuth provider redirect amplifies this. Polling sidesteps the whole opener relationship and works regardless of COOP, OAuth, or the user opening the link in a new tab.
> 
> \## Setting
> 
> \- \`embed\_full\_app\_signin\_flow\` (boolean, default \`true\`, in the \`embedding\` area).
> \- The flow assumes the iframe can receive its cookies after popup sign-in — true when the embed is \*\*same-site to the host page\*\* (any SameSite setting) or when \`same\_site\_cookies = "None"\` is configured for cross-site embeds. We trust the admin to enable this only on a compatible deployment.
> 
> \## Implementation notes
> 
> \- \*\*Browser-agnostic storage access.\*\* \`hasStorageAccess()\` is the single signal — \`true\` on same-site/same-origin embeds (no prompt needed), \`false\` whenever the iframe's cookie jar is partitioned. No browser sniffing.
> \- \*\*User activation preserved.\*\* The modal uses native \`\<button {{on "click" handler}}\>\` rather than \`service:dialog\`, so \`requestStorageAccess()\` and \`window.open()\` see a live activation token in the click handler.
> \- \*\*No reload after storage access.\*\* \`requestStorageAccess()\` grants access for the current document; we chain directly into the next step in the same execution. Reloading would put the iframe back in partitioned mode in most browsers.
> \- \*\*Popup self-close is param-driven, not opener-driven.\*\* The callback initializer keys off \`?embed\_signin\_callback=1\` alone — \`window.opener\` is unreliable thanks to COOP.
> \- \*\*API-unsupported fallback.\*\* Without \`document.requestStorageAccess\`, the service opens a plain top-level login tab (no callback param) instead of trapping the user in a popup that cannot bridge cookies.
> \- \*\*Storage access denial is a dead-end on purpose.\*\* The catch handler does not chain to a sign-in popup, since a sign-in tab cannot help an iframe that lacks storage access. The user retries the action to be re-prompted.
> \- \*\*Waiting modal.\*\* While polling, the iframe shows a spinner and "Waiting for sign-in" message. Cancel stops the poll and closes the popup; the modal auto-dismisses on timeout.
> 
> \## Tests
> 
> \`tests/unit/services/embed-auth-flow-test.js\` covers gating, the partitioned vs. non-partitioned split, the storage-access → sign-in chain, the already-signed-in → reload path, denial behaviour, popup URL routing, and the API-unsupported fallback.

---

_[View the full topic](https://meta.discourse.org/t/tecnoblogs-experience-with-discourse-comments/400721)._
