Atmosphere 登录

本页内容

@emdash-cms/auth-atproto 软件包为 EmDash 增加使用 Atmosphere 账号 登录的选项。Atmosphere 账号是可携带的、用户自持的身份,可在 Bluesky 及 AT 协议网络上的其他应用间通用。用户使用自己的句柄(例如 alice.bsky.social)登录,并在其所属的身份服务提供商处完成验证 —— EmDash 永远不会看到密码。

在以下场景尤为合适:

  • 你的协作者已经拥有 Atmosphere 账号。
  • 你希望管控组织名下的域名(*.yourcompany.com),又不想维护 OAuth 应用或邀请制。
  • 你正在构建属于更广泛 Atmosphere 生态的一部分,并希望与栈中其余部分保持统一的身份体系。

安装

pnpm add @emdash-cms/auth-atproto
import { defineConfig } from "astro/config";
import emdash from "emdash/astro";
import { atproto } from "@emdash-cms/auth-atproto";

export default defineConfig({
	integrations: [
		emdash({
			authProviders: [atproto()],
			server: {
				host: "127.0.0.1", // 本地开发必需 —— 见下文「本地开发」
			},
		}),
	],
});

这样便足以在登录页和设置向导中显示 使用 Atmosphere 登录。若未配置任何白名单,首位注册用户会成为管理员,此后对所有其他人关闭自助注册 —— 请参阅白名单以放宽限制。

无需配置环境变量、客户端密钥或注册 OAuth 应用。该提供方是公开的 OAuth 客户端,并在 /.well-known/atproto-client-metadata.json 提供自身的元数据文档。

配置

atproto({
	allowedDIDs: ["did:plc:abc123..."],
	allowedHandles: ["*.example.com", "alice.bsky.social"],
	defaultRole: 30, // 作者
});
选项类型默认值说明
allowedDIDsstring[]无(首位用户之前允许所有人)DID 白名单。DID 永久且无法伪造。
allowedHandlesstring[]无(首位用户之前允许所有人)句柄白名单。支持通配符(*.example.com)。
defaultRolenumber10(订阅者)首位之后的获准用户被分配的角色。首位用户始终是管理员。

完整角色阶梯见主文档 身份验证指南

白名单

若既未设置 allowedDIDs 也未设置 allowedHandles,则只有首位用户可以注册 —— 任何其他人尝试登录都会收到 signup_not_allowed 而被拒绝。已存在的用户始终可以再次登录,与当前白名单无关(因此把自己从列表中移除不会把你锁在外面,但也不会让新用户加入)。

当至少配置了一项白名单时,用户满足任一列表条件即可准入:

  • DID 匹配。 用户的 DID 位于 allowedDIDs 中。DID 是密码学标识符,无法迁移或冒充,因此这是最严格的门禁方式。
  • 句柄匹配。 用户的句柄与 allowedHandles 中的某一项完全匹配,或通过前导通配符模式匹配(*.example.com 可同时匹配 alice.example.combob.team.example.com)。

尽管句柄可变更,句柄白名单仍然是安全的。在因句柄匹配而允许用户进入之前,EmDash 会独立解析该句柄的 DNS/HTTP 记录,并验证其是否指向身份服务提供方所声称的同一 DID。行为异常的服务提供方不能凭空声称拥有 [email protected]

默认角色

获准用户会获得你在 defaultRole 中设置的角色。只有完成站点初始设置的首位用户会被强制设为管理员。Atmosphere 账号没有群组/角色映射;若需要更细粒度的角色,请在用户至少登录一次后,到 设置 → 用户 中调整。

首位用户设置

当你在新站点上启用了 Atmosphere 提供方,设置向导会将其提供为创建初始管理员账号的选项之一。

  1. 访问 /_emdash/admin。设置向导会引导你填写站点标题、标语和管理员邮箱。

  2. 在「创建管理员账号」步骤,选择 Atmosphere 并输入你的句柄(例如 alice.bsky.social)。

  3. 你会被重定向到你账号的授权页面,按该服务提供方支持的方式登录 —— 密码、通行密钥或其他方式。

  4. 同意后你会回到 EmDash,系统会创建角色为 50(管理员)的管理员用户,并在第 1 步填写的邮箱会保存到你的账号上。

此后每次登录都走同一流程 —— 输入句柄、跳转到你的提供方、再跳回,即完成登录。

本地开发

AT 协议 OAuth 规范要求环回(loopback)重定向 URI 使用 IP 字面量127.0.0.1[::1]),不能使用 localhost。EmDash 在生成重定向 URI 时会透明地将 ://localhost 改写为 ://127.0.0.1,但这意味着你的开发会话也需要在 127.0.0.1 上启动 —— 否则在 localhost 上设置的会话 cookie 在重定向落到 127.0.0.1 后将无法被读取。

Astro 的开发服务器基于 Vite,而 Vite 默认监听 localhost。请让开发服务器也绑定到环回 IP:

export default defineConfig({
	server: {
		host: "127.0.0.1",
	},
	// ...
});

然后全程使用 http://127.0.0.1:4321/_emdash/admin 打开管理后台。

生产环境

生产环境无需额外配置。该提供方在以下地址提供自身的客户端元数据:

https://your-site.example.com/.well-known/atproto-client-metadata.json

授权服务器在登录过程中会拉取该 URL,以校验客户端的重定向 URI。请确保部署站点的站点 URL 可通过公网 HTTPS 访问 —— 仅在 VPN 后的内网部署无法完成登录,因为用户的授权服务器无法获取该元数据文档。

若 EmDash 运行在终结 TLS 的反向代理之后,请设置 siteUrl,以便 EmDash 生成正确的重定向 URI。否则请求可能表现为 http://internal-host:4321,元数据将与授权服务器所见不一致。

故障排除

「账号不在白名单中」

你用于登录的句柄或 DID 不在 allowedDIDs / allowedHandles 中。检查通配符模式(必须以 *. 开头),并记住句柄匹配会针对 DNS/HTTP 做校验 —— 若句柄的 DID 记录当前解析到的 DID 与提供方返回的不一致,匹配会被拒绝。

「不允许自助注册」

你已顺利到达回调,但未配置白名单且你不是首位用户。请把自己加入 allowedDIDs/allowedHandles,或由现有管理员邀请你,使在你登录前用户记录已存在。

登录后又跳回登录页且没有错误信息

几乎总是 本地开发 一节所述的环回 cookie 问题。在设置 server.host: "127.0.0.1" 后,使用 http://127.0.0.1:4321 打开管理后台再试。

自托管句柄的解析失败

提供方通过竞速 DNS-over-HTTPS(Cloudflare 的 DoH 端点)与 HTTP /.well-known/atproto-did 查询来校验句柄。自托管句柄至少需要满足以下之一

  • _atproto.<句柄> 的 DNS TXT 记录,内容为 did=<你的-did>,或
  • https://<句柄>/.well-known/atproto-did 文件,内容为该 DID。

若两种方式都失败,即使底层账号有效,句柄匹配也会被拒绝。allowedDIDs 中的 DID 不受影响 —— 它们直接匹配。