我的 Discourse 网站上有一个 JS 插件。这个 JS 使用 pocketbase 来存储数据。Pocketbase 是一个“无服务器”的 SQLite 服务,允许我存储文件和 JSON 块。Pocketbase 有一个出色的基于 JWT 的身份验证系统,因此一旦用户拥有身份验证令牌,他们就可以直接从客户端的 JS 安全地将数据存储到 pocketbase(无需通过后端服务器等进行代理)。
我正在尝试找到一种方法,可以在用户登录 Discourse 时自动在 pocketbase 端生成登录。
我的第一次尝试是让 JS 插件调用服务器上的一个路径,并包含 Discourse 的身份验证 cookie。然后,对于该路径,让 nginx 将其代理到一个服务(“登录代理”),该服务可以解码身份验证 cookie 并确定用户是谁。通过验证的用户信息,登录代理随后可以向 pocketbase 发出特殊调用,获取 pocketbase 身份验证 cookie,然后将该 pocketbase 身份验证 cookie 发回,客户端 JS 可以使用该 cookie 直接向 pocketbase 发出后续请求。
但是,我在解码 Discourse 身份验证 cookie 时遇到了麻烦(我想 _t 是正确的 cookie,但我没有简单的方法来获取用户信息,并且担心其结构可能会发生变化)。
有没有更聪明的方法可以安全地获取已登录用户的电子邮件地址?我认为这不应该在客户端进行,出于明显的安全原因,我更希望在服务器端进行。
renato
(Renato Atilio)
2024 年12 月 4 日 15:36
2
我不知道你的技术栈或用例足够多,但我认为我以前解决过类似的问题,有些想法可能对你有用。
我有一个 Next.js 应用程序,我需要客户端拥有一个有效的 JWT 来调用我的后端 API(如果存在 Discourse 会话)。
为此,我使用 Discourse 作为我的身份提供者,通过 DiscourseConnect 。
在我的例子中,我通过一个客户端 fetch 调用 { credentials: "include" } 来实现这一点,这之所以有效是因为我所有的设置都在同一个域下,并且 fetch 调用会自动跟随重定向。
我的客户端获取一个自定义的 /auth/token,它会检查 _t 的存在(只是为了避免不必要的重定向),然后根据链接主题中的文档,返回一个重定向到安全的 /session/sso_provider URL,该 URL 包含 nonce/sso/sig,以及一个指向自定义 /auth/callback 的 return_sso_url。该回调将提取 Discourse 发送的数据,构建并返回一个 JWT 令牌,我的客户端从此时起可以使用该令牌。
我相信你的用例也可以用类似的方式解决。
So you want to use Discourse as an identity provider for your own web app? Great! Let’s get started.
Enable DiscourseConnect provider setting
Under Discourse admin site settings (/admin/site_settings) enable setting enable discourse connect provider and add a secret string to discourse connect provider secrets (used to hash SSO payloads).
Implement DiscourseConnect in your web app:
Generate a random nonce . Let’s call this value NONCE. Save it temporarily so that you can verify it with the …
@renato 如果您不介意,我有几个问题。
这是否意味着我需要将用户管理身份验证的全部内容委托给 connect 应用?如果真是这样,我不确定我是否愿意这样做。
如果 connect 只是现有 discourse 用户身份验证管理之上的一个附加层,那么这似乎是可行的。
但是,当我开始阅读 discourse connect 的相关内容时,我担心我现在需要构建和维护一个全新的应用程序来管理用户身份验证,而我现在真的不知道如何确定其范围。
renato
(Renato Atilio)
2024 年12 月 4 日 16:27
5
我的答案假设您正在使用 Discourse 作为您的身份提供商(使用其登录/注册 UI),并且希望保持这种状态。
在 Discourse 端,启用它就像启用设置 enable discourse connect provider 并向 discourse connect provider secrets(用于哈希 SSO 有效负载)添加一个秘密字符串一样简单。
但是,您提到您正在构建一个插件。
如果您在 Discourse 插件的新控制器操作中构建“服务器上的一个路径”,您可以从会话中获取用户,调用第三方服务,并将 JWT 返回给您的客户端。
非常感谢您的讨论。
我阅读了链接:Use Discourse as an identity provider (SSO, DiscourseConnect) - #8 by reverend_paco
但我认为这适用于我想将用户发送到二级站点并在那里管理身份验证的情况。
在我的例子中,我在 discourse 站点上运行了一段 JS。我想让该 JS 调用同一服务器上的一个路径,并为 pocketbase 获取一个 cookie。
我实际上在 discourse 前面使用了一个 nginx 代理,所以我添加了一个特殊的路由 /pb/auth(例如)。当我的 JS 命中该路由时,一个后端代理服务器(不在 discourse 内部)会接受该连接,并尝试解码 _t 会话 cookie。
我之所以这样做,是因为它似乎比添加一个 discourse 插件(我对它和开发设置不太熟悉等)要容易一些。如果只是用 base64 和 sha 哈希解码 cookie 的简单方法,我认为这可以提供一个安全的有效载荷来告诉我用户是谁。
但是,如果您认为有一个简单的方法可以构建一个插件来将此路由添加到 discourse,我非常有兴趣尝试一下。这似乎是长远来看正确的方法。但我是一名老式的 Perl 程序员,所以我更喜欢走捷径,而我的 nginx 路由似乎更省事。
renato
(Renato Atilio)
2024 年12 月 4 日 16:50
7
恰恰相反:如果您有一个单独的“站点”(在此示例中为 PocketBase),并希望 Discourse 成为用户/身份验证管理的真相来源——就像我的 Next.js 示例一样。
我会从阅读开始
Over time Discourse has grown in complexity and it can be daunting for beginners to understand how data gets all the way from the back end Ruby on Rails application to the Ember.js application in front.
This tutorial is meant to show the full lifecycle of a request in Discourse and explain the steps necessary if you want to build a new page with its own URL in our application.
URLs First
I always prefer to start thinking of features in terms of the URLs to access them. For example let’s say we…
太好了,我很期待阅读。我开始查看示例骨架插件 (GitHub - discourse/discourse-plugin-skeleton: Template for Discourse plugins ),但有点失望,因为它完全没有文档。
乍一看,我需要问:本教程是否在 discourse 的基础 rails 安装中添加代码?如果这是官方方法,我没问题,但感觉这很危险,并且最好通过插件来处理(插件可以轻松卸载、禁用)。另外,我不用担心我的代码不在 github 仓库中,这会破坏 discourse 的升级吗?
例如在这里:
Over time Discourse has grown in complexity and it can be daunting for beginners to understand how data gets all the way from the back end Ruby on Rails application to the Ember.js application in front.
This tutorial is meant to show the full lifecycle of a request in Discourse and explain the steps necessary if you want to build a new page with its own URL in our application.
URLs First
I always prefer to start thinking of features in terms of the URLs to access them. For example let’s say we…
这是否意味着我真的要进入容器 (./launcher enter app),然后编辑 /var/www/app/controllers/snack_controller.rb?
而且,我确实刚刚遵循了这些说明。即使运行 ./launcher rebuild app 后,我也无法让 /admin/snack.json 路由正常工作。
本教程看起来已有大约八年历史。这真的是做事的正确方法吗?
renato
(Renato Atilio)
2024 年12 月 4 日 17:48
9
还有其他指南,顶部的日期是主题创建日期,但 Documentation 中的任何内容都应是最新的 – 如果您发现任何问题,请告知我们。
您可以查看现有 Plugin 的代码作为参考。
Chris Dawson:
这是否意味着我真的要进入容器
不:
This guide assumes that you have a self-hosted standard installation. We only support the standard method of install here, so these instructions assume you have a standard install .
This guide only applies to self-hosted Discourse instances. If you are using a managed hosting service, the available plugins are controlled by your hosting provider. For example, on our hosting these specific plugins are available by hosting tier.
In this tutorial, we’ll install the Discours…
Moin
2024 年12 月 4 日 18:02
10
2 个赞
好的,我尝试遵循了说明。我尝试在容器内 使用命令 rake plugin:create[pocketbase-auth](因为容器外无法使用 rake)。但由于容器内没有设置 git,命令失败了。
我进一步阅读,发现需要指定插件的 git 仓库才能在管理后台显示插件。但我还没有一个勉强可用的插件版本,也没有将代码放在 git 仓库中。
编辑 :我没有仔细阅读,确实这需要一个开发环境,这在开头已经清楚说明了。我将着手处理这个问题,然后再回来。
我怀疑这些困难是因为插件通常是针对 discourse 的“开发”环境开发的,而不是在我运行的 docker 容器内。这没关系,但我希望插件开发者指南能从这个假设开始,并提供在此环境下运行的说明。推荐的 discourse 运行方式是使用 docker(我非常喜欢),但我认为在 docker 内运行和在文档中进行开发之间存在差距。
# rake plugin:create[pocketbase-auth]
Cloning 'https://github.com/discourse/discourse-plugin-skeleton' to '/var/www/discourse/plugins/pocketbase-auth'...
Initializing git repository...
hint: Using 'master' as the name for the initial branch. This default branch name
hint: is subject to change. To configure the initial branch name to use in all
hint: of your new repositories, which will suppress this warning, call:
hint:
hint: git config --global init.defaultBranch <name>
hint:
hint: Names commonly chosen instead of 'master' are 'main', 'trunk' and
hint: 'development'. The just-created branch can be renamed via this command:
hint:
hint: git branch -m <name>
Initialized empty Git repository in /var/www/discourse/plugins/pocketbase-auth/.git/
Author identity unknown
*** Please tell me who you are.
Run
git config --global user.email "you@example.com"
git config --global user.name "Your Name"
to set your account's default identity.
Omit --global to set the identity only in this repository.
fatal: unable to auto-detect email address (got 'discourse@community-public-do-vm-app.(none)')
rake aborted!
Command failed with exit 128: git
/var/www/discourse/lib/tasks/plugin.rake:356:in `system'
/var/www/discourse/lib/tasks/plugin.rake:356:in `block (2 levels) in <main>'
/var/www/discourse/lib/tasks/plugin.rake:346:in `chdir'
/var/www/discourse/lib/tasks/plugin.rake:346:in `block in <main>'
/usr/local/bin/bundle:25:in `load'
/usr/local/bin/bundle:25:in `<main>'
Tasks: TOP => plugin:create
(See full trace by running task with --trace)
更新:我采纳了您的建议,开发了一个插件。它运行良好,完全符合我的需求。感谢您的帮助。
1 个赞
system
(system)
关闭
2025 年1 月 5 日 01:24
13
This topic was automatically closed 30 days after the last reply. New replies are no longer allowed.