Update zh-cn translations
This commit is contained in:
parent
5e2b739ee1
commit
a939c23559
168 changed files with 36955 additions and 1406 deletions
898
content/zh-cn/spec/activitypub.md
Normal file
898
content/zh-cn/spec/activitypub.md
Normal file
|
@ -0,0 +1,898 @@
|
|||
---
|
||||
title: ActivityPub
|
||||
description: 基于 ActivityStreams 2.0 数据格式和 JSON-LD 的去中心化社交网络协议。
|
||||
menu:
|
||||
docs:
|
||||
weight: 10
|
||||
parent: spec
|
||||
---
|
||||
|
||||
## 嘟文的联合 {#status}
|
||||
|
||||
{{< caption-link url="https://github.com/mastodon/mastodon/blob/main/app/lib/activitypub/activity.rb" caption="app/lib/activitypub/activity.rb" >}}
|
||||
|
||||
### 嘟文支持的 Activity 类型
|
||||
|
||||
Create
|
||||
: 转换为嘟文并保存到数据库中
|
||||
|
||||
Delete
|
||||
: 从数据库中删除嘟文
|
||||
|
||||
Like
|
||||
: 转换为嘟文的点赞
|
||||
|
||||
Announce
|
||||
: 转换为嘟文的转发
|
||||
|
||||
Update
|
||||
: 刷新投票计数(针对投票)。自 Mastodon 3.5.0 起:当存在 `updated` 时间戳时,编辑嘟文。
|
||||
|
||||
Undo
|
||||
: 撤销之前的 Like 或 Announce。
|
||||
|
||||
Flag
|
||||
: 转换为向审核团队的举报。更多信息请查看 [举报](#Flag) 扩展。
|
||||
|
||||
### 载荷
|
||||
|
||||
Mastodon 主要支持的对象类型为 `Note` 和 `Question`。
|
||||
|
||||
- Notes 会转换为常规嘟文。
|
||||
- Questions 会转换为投票嘟文。更多信息请查看 [投票](#Question) 扩展。
|
||||
|
||||
某些其他对象类型会尽可能地进行转换:
|
||||
|
||||
- Article
|
||||
- Page
|
||||
- Image
|
||||
- Audio
|
||||
- Video
|
||||
- Event
|
||||
|
||||
转换器会使用 `content` 属性(如果可用),否则使用 `name` 属性来生成嘟文文本。 `url` 属性将会被追加到文本之后。 `summary` 属性将被用作内容警告 (CW) 文本。 `icon` 属性将被用作缩略图。
|
||||
|
||||
### HTML 清洗 {#sanitization}
|
||||
|
||||
{{< caption-link url="https://github.com/mastodon/mastodon/blob/main/lib/sanitize_ext/sanitize_config.rb" caption="lib/sanitize_ext/sanitize_config.rb" >}}
|
||||
|
||||
Mastodon 会清洗接收到的 HTML,以避免破坏 API 客户端开发者的假设。受支持的元素将保持原样,不受支持的元素将被转换或移除。受支持的属性将被保留,所有其他属性将被剥离。以下是支持的元素和属性:
|
||||
|
||||
- `<p>`
|
||||
- `<span>` (`class`)
|
||||
- `<br>`
|
||||
- `<a>` (`href`, `rel`, `class`)
|
||||
- 列表将会被转换为 `<p>`,并且列表项之间会用 `<br>` 分隔
|
||||
|
||||
自 Mastodon v4.2 起,支持以下元素和属性:
|
||||
|
||||
- `<p>`
|
||||
- `<span>` (`class`)
|
||||
- `<br>`
|
||||
- `<a>` (`href`, `rel`, `class`)
|
||||
- `<del>`
|
||||
- `<pre>`
|
||||
- `<code>`
|
||||
- `<em>`
|
||||
- `<strong>`
|
||||
- `<b>`
|
||||
- `<i>`
|
||||
- `<u>`
|
||||
- `<ul>`
|
||||
- `<ol>` (`start`, `reversed`)
|
||||
- `<li>` (`value`)
|
||||
- `<blockquote>`
|
||||
- 标题将会被转换为 `<strong>`,然后包裹在 `<p>` 中
|
||||
|
||||
清洗器会保留以 microformats 前缀开头或属于语义类的 class:
|
||||
|
||||
- h-*
|
||||
- p-*
|
||||
- u-*
|
||||
- dt-*
|
||||
- e-*
|
||||
- mention
|
||||
- hashtag
|
||||
- ellipsis
|
||||
- invisible
|
||||
|
||||
如果链接协议受支持,则链接将被保留,否则将被转换为文本。以下是受支持的链接协议:
|
||||
|
||||
- http
|
||||
- https
|
||||
- dat
|
||||
- dweb
|
||||
- ipfs
|
||||
- ipns
|
||||
- ssb
|
||||
- gopher
|
||||
- xmpp
|
||||
- magnet
|
||||
- gemini
|
||||
|
||||
### 使用的属性
|
||||
|
||||
content
|
||||
: 用作嘟文文本
|
||||
|
||||
name
|
||||
: 用作嘟文文本(如果要转换的对象类型没有提供 `content`)
|
||||
|
||||
summary
|
||||
: 用作内容警告 (CW) 文本
|
||||
|
||||
sensitive
|
||||
: 用于确定嘟文媒体或文本是否应默认隐藏。有关 `as:sensitive` 的更多信息,请查看 [敏感内容](#sensitive) 扩展部分
|
||||
|
||||
inReplyTo
|
||||
: 用于将嘟文作为回复串联到另一个嘟文
|
||||
|
||||
published
|
||||
: 用作嘟文日期
|
||||
|
||||
url
|
||||
: 用于嘟文永久链接,并且也会附加到转换对象的文本中
|
||||
|
||||
attributedTo
|
||||
: 用于确定嘟文的作者的账户
|
||||
|
||||
to/cc
|
||||
: 结合 mentions 一起使用,以确定嘟文的受众和可见性。请查看 [用于寻址和通知的 Mentions](#Mention)
|
||||
|
||||
tag
|
||||
: 用于标记 mentions 和 hashtags。
|
||||
|
||||
tag[].type
|
||||
: 当前支持 `Mention`、`Hashtag` 或 `Emoji`。有关更多信息,请查看 [话题标签](#Hashtag) 和 [自定义表情](#Emoji) 扩展部分
|
||||
|
||||
tag[].name
|
||||
: 账户 Mention 的纯文本 Webfinger 地址(`@user` 或 `@user@domain`)、纯文本话题标签(`#tag`)或自定义 Emoji 短代码(`:thounking:`)
|
||||
|
||||
tag[].href
|
||||
: 请求体或标签的 URL
|
||||
|
||||
attachment
|
||||
: 用于包含附加的图片、视频或音频。
|
||||
|
||||
attachment[].url
|
||||
: 用于获取媒体附件
|
||||
|
||||
attachment[].summary
|
||||
: 用作媒体描述
|
||||
|
||||
attachment[].blurhash
|
||||
: 用于生成与图像中使用的颜色相对应的模糊预览图像。有关更多详细信息,请查看 [Blurhash](#blurhash)。
|
||||
|
||||
replies
|
||||
: 回复当前嘟文的嘟文集合。为了更完整地解析嘟文串,在发现外站嘟文后,将从同一实例获取最多 5 条回复。在 Mastodon 侧,第一页包含嘟文作者自己的回复,而之后的页面包含来自其他人的回复。
|
||||
|
||||
likes
|
||||
: 用于表示为此嘟文收到的 `Like` 活动的集合。Mastodon 目前不公开实际的活动。
|
||||
|
||||
likes.totalItems
|
||||
: 此嘟文收到的点赞数。
|
||||
|
||||
shares
|
||||
: 用于表示为此嘟文收到的 `Announce` 活动的集合。Mastodon 目前不公开实际的活动。
|
||||
|
||||
shares.totalItems
|
||||
: 此嘟文收到的 `Announce` 活动的数量。
|
||||
|
||||
#### 投票特定的属性
|
||||
|
||||
endTime
|
||||
: 投票结束的时间戳
|
||||
|
||||
closed
|
||||
: 投票结束的时间戳。该时间戳很可能与 `endTime` 时间戳匹配。如果此属性存在,则假定投票已结束。
|
||||
|
||||
votersCount
|
||||
: 参与投票的人数,与已投出的票数(在多项选择投票的情况下)不同
|
||||
|
||||
oneOf
|
||||
: 单项选择投票选项
|
||||
|
||||
anyOf
|
||||
: 多项选择投票选项
|
||||
|
||||
oneOf/anyOf[].name
|
||||
: 投票选项的文本
|
||||
|
||||
oneOf/anyOf[].replies.totalItems
|
||||
: 投票选项的投票数
|
||||
|
||||
## 账户的联合 {#profile}
|
||||
|
||||
### 账户支持的 Activity 类型
|
||||
|
||||
Follow
|
||||
: 表示对接收来自账户的嘟文更新感兴趣。
|
||||
|
||||
Accept/Reject
|
||||
: 用于批准或拒绝 Follow 活动。未锁嘟的帐户将自动回复 Accept,而锁嘟的帐户可以手动选择是批准还是拒绝关注请求。
|
||||
|
||||
Add/Remove
|
||||
: 管理置顶嘟文和精选内容。
|
||||
|
||||
Update
|
||||
: 刷新帐户详细信息
|
||||
|
||||
Delete
|
||||
: 从数据库中删除帐户及其所有嘟文。
|
||||
|
||||
Undo
|
||||
: 撤销之前的 Follow、Accept Follow 或 Block。
|
||||
|
||||
Block
|
||||
: 向外站实例发出信号,表明应对该用户隐藏你的账户。不作生效保证。有关更多信息,请查看 [外站屏蔽](#Block)。
|
||||
|
||||
Flag
|
||||
: 向对方审核团队举报用户。有关更多信息,请查看 [举报](#Flag) 扩展。
|
||||
|
||||
Move
|
||||
: 将关注者从一个帐户迁移到另一个帐户。要求在新帐户上设置指向旧帐户的 `alsoKnownAs`。
|
||||
|
||||
### 使用的属性
|
||||
|
||||
preferredUsername
|
||||
: 用于 Webfinger 查找。必须在此域上唯一存在,且必须对应于 Webfinger `acct:` URI。
|
||||
|
||||
name
|
||||
: 用作账户显示名称。
|
||||
|
||||
summary
|
||||
: 用作账户简介。
|
||||
|
||||
type
|
||||
: 假定为 Person。如果类型为 Application 或 Service,则将其解释为机器人标志。
|
||||
|
||||
url
|
||||
: 用作账户链接。
|
||||
|
||||
icon
|
||||
: 用作账户头像。
|
||||
|
||||
image
|
||||
: 用作账户标题。
|
||||
|
||||
manuallyApprovesFollowers
|
||||
: 将显示为锁嘟的帐户。
|
||||
|
||||
discoverable
|
||||
: 将显示在账户目录中。请查看 [可发现标志](#discoverable)。
|
||||
|
||||
indexable
|
||||
: 此帐户的嘟文可以被索引以进行全文搜索。请查看 [可索引标志](#indexable)。
|
||||
|
||||
publicKey
|
||||
: 签名必需的属性。请查看 [公钥](#publicKey)。
|
||||
|
||||
featured
|
||||
: 置顶嘟文。请查看 [特色收藏集](#featured)。
|
||||
|
||||
attachment
|
||||
: 用于账户字段。请查看 [账户元数据](#PropertyValue) 和 [身份证明](#IdentityProof)。
|
||||
|
||||
alsoKnownAs
|
||||
: Move 活动必需。
|
||||
|
||||
published
|
||||
: 账户的创建时间。
|
||||
|
||||
memorial
|
||||
: 该帐户是否为悼念帐户。
|
||||
|
||||
suspended
|
||||
: 该帐户当前是否被封禁。
|
||||
|
||||
attributionDomains
|
||||
: 允许在已发布的嘟文中使用此 actor 的 `fediverse:creator` 的域。
|
||||
|
||||
## JSON-LD 上下文和扩展 {#contexts}
|
||||
|
||||
{{< caption-link url="https://github.com/mastodon/mastodon/blob/main/app/lib/activitypub/adapter.rb" caption="app/lib/activitypub/adapter.rb" >}}
|
||||
|
||||
### Mastodon 扩展 (`toot:`) {#toot}
|
||||
|
||||
基础 URI: `http://joinmastodon.org/ns#`
|
||||
|
||||
包含用于 Mastodon 功能的术语。
|
||||
|
||||
- toot:Emoji (`http://joinmastodon.org/ns#Emoji`)
|
||||
- toot:IdentityProof (`http://joinmastodon.org/ns#IdentityProof`)
|
||||
- toot:attributionDomains (`http://joinmastodon.org/ns#attributionDomains`)
|
||||
- toot:blurhash (`http://joinmastodon.org/ns#blurhash`)
|
||||
- toot:discoverable (`http://joinmastodon.org/ns#discoverable`)
|
||||
- toot:featured (`http://joinmastodon.org/ns#featured`)
|
||||
- toot:featuredTags (`http://joinmastodon.org/ns#featuredTags`)
|
||||
- toot:focalPoint (`http://joinmastodon.org/ns#focalPoint`)
|
||||
- toot:indexable (`http://joinmastodon.org/ns#indexable`)
|
||||
- toot:memorial (`http://joinmastodon.org/ns#memorial`)
|
||||
- toot:suspended (`http://joinmastodon.org/ns#suspended`)
|
||||
- toot:votersCount (`http://joinmastodon.org/ns#votersCount`)
|
||||
|
||||
### ActivityStreams 扩展 (`as:`) {#as}
|
||||
|
||||
基础 URI: `https://www.w3.org/ns/activitystreams#`
|
||||
|
||||
包含已提出但尚未被正式采用的 ActivityStreams 扩展属性。
|
||||
|
||||
- as:Hashtag (`https://www.w3.org/ns/activitystreams#Hashtag`)
|
||||
- as:manuallyApprovesFollowers (`https://www.w3.org/ns/activitystreams#manuallyApprovesFollowers`)
|
||||
- as:movedTo (`https://www.w3.org/ns/activitystreams#movedTo`)
|
||||
- as:sensitive (`https://www.w3.org/ns/activitystreams#sensitive`)
|
||||
|
||||
### Schema.org 扩展 (`schema:`) {#schema}
|
||||
|
||||
包含用于账户元数据的属性。
|
||||
|
||||
基础 URI: `http://schema.org#` (错误; 应为 `https://schema.org/`)
|
||||
|
||||
- [schema:PropertyValue (`http://schema.org#PropertyValue`, 应该是 `https://schema.org/PropertyValue`)](https://schema.org/PropertyValue)
|
||||
- [schema:value (`http://schema.org#value`, 应该是 `https://schema.org/value`)](https://schema.org/value)
|
||||
|
||||
### W3ID 安全词汇 (`sec:`) {#sec}
|
||||
|
||||
上下文:[`https://w3id.org/security/v1`](https://w3id.org/security/v1)
|
||||
|
||||
用于 HTTPS 签名。也用于身份证明。有关更多信息,请查看 [安全]({{< relref "spec/security" >}})。
|
||||
|
||||
- [sec:publicKey (`https://w3id.org/security#publicKey`)](https://w3id.org/security#publicKey)
|
||||
- [sec:publicKeyPem (`https://w3id.org/security#publicKeyPem`)](https://w3id.org/security#publicKeyPem)
|
||||
- [sec:owner (`https://w3id.org/security#owner`)](https://w3id.org/security#owner)
|
||||
- [sec:signature (`https://w3id.org/security#signature`)](https://w3id.org/security#signature)
|
||||
- [sec:signatureValue (`https://w3id.org/security#signatureValue`)](https://w3id.org/security#signatureValue)
|
||||
|
||||
#### W3ID 身份
|
||||
|
||||
上下文:[`https://w3id.org/identity/v1`](https://w3id.org/identity/v1) (离线)
|
||||
|
||||
用于链接数据签名。有关更多信息,请查看 [安全 > 链接数据签名]({{< relref "spec/security#ld" >}})。
|
||||
|
||||
- [dc:creator (`http://purl.org/dc/terms/creator`)](http://purl.org/dc/terms/creator)
|
||||
- [dc:created (`http://purl.org/dc/terms/created`)](http://purl.org/dc/terms/created)
|
||||
- [sec:signature (`https://w3id.org/security#signature`)](https://w3id.org/security#signature)
|
||||
- [sec:signatureValue (`https://w3id.org/security#signatureValue`)](https://w3id.org/security#signatureValue)
|
||||
|
||||
## 使用 ActivityStreams 词汇表定义的扩展
|
||||
|
||||
虽然 Activity 术语表定义了各种类型和术语,但 ActivityPub 仅为其中的一部分定义了副作用。以下 Activity 类型在 Mastodon 收件箱中收到时具有以下副作用。
|
||||
|
||||
### 外站屏蔽 (`Block`) {#Block}
|
||||
|
||||
ActivityPub 为客户端到服务端 (C2S) 用例定义了 `Block` 活动,但不适用于服务端到服务端 (S2S) — 它建议实例不应将 Block 活动传递给其 `object`。但是,当本站用户屏蔽外站用户时,Mastodon 将发送此活动。当 Mastodon 收到 `object` 是本站域名上的 actor 的 `Block` 活动时,它会将其解释为信号,以对本站用户隐藏对应 actor 的账户和嘟文,以及禁止该本站用户提及该 actor。
|
||||
|
||||
```json
|
||||
{
|
||||
"@context": "https://www.w3.org/ns/activitystreams",
|
||||
"id": "https://mastodon.example/bd06bb61-01e0-447a-9dc8-95915db9aec8",
|
||||
"type": "Block",
|
||||
"actor": "https://mastodon.example/users/alice",
|
||||
"object": "https://example.com/~mallory",
|
||||
"to": "https://example.com/~mallory"
|
||||
}
|
||||
```
|
||||
|
||||
### 举报账户和嘟文 (`Flag`) {#Flag}
|
||||
|
||||
要举报外站实例上的账户和/或嘟文,Mastodon 将向实例 actor 发送 `Flag` 活动。此活动的 `object` 包含被举报的用户以及任何附加到该举报的嘟文。如果举报附有评论,它将用作活动的 `content`。
|
||||
|
||||
```json
|
||||
{
|
||||
"@context": "https://www.w3.org/ns/activitystreams",
|
||||
"id": "https://mastodon.example/ccb4f39a-506a-490e-9a8c-71831c7713a4",
|
||||
"type": "Flag",
|
||||
"actor": "https://mastodon.example/actor",
|
||||
"content": "请查看此用户及其嘟文",
|
||||
"object": [
|
||||
"https://example.com/users/1",
|
||||
"https://example.com/posts/380590",
|
||||
"https://example.com/posts/380591"
|
||||
],
|
||||
"to": "https://example.com/users/1"
|
||||
}
|
||||
```
|
||||
|
||||
### 帐户迁移 (`Move`) {#Move}
|
||||
|
||||
Mastodon 使用 Move 活动来指示帐户已迁移到另一个帐户。为了使迁移被视为有效,Mastodon 检查新帐户是否(通过 `alsoKnownAs` 属性)设置了指向旧帐户的别名。
|
||||
|
||||
```json
|
||||
{
|
||||
"@context": "https://www.w3.org/ns/activitystreams",
|
||||
"id": "https://mastodon.example/users/alice#moves/1",
|
||||
"actor": "https://mastodon.example/users/alice",
|
||||
"type": "Move",
|
||||
"object": "https://mastodon.example/users/alice",
|
||||
"target": "https://alice.com/users/109835986274379",
|
||||
"to": "https://mastodon.example/users/alice/followers"
|
||||
}
|
||||
```
|
||||
|
||||
### 投票 {#Question}
|
||||
|
||||
{{< caption-link url="https://www.w3.org/TR/activitystreams-vocabulary/#questions" caption="Activity Vocabulary §5.4 - Representing Questions" >}}
|
||||
|
||||
ActivityStreams 词汇表规范松散地(非规范地)描述了如何表示问题。 Mastodon 的投票实现受到该节的启发。可以观察到以下实现细节:
|
||||
|
||||
- `Question` 被用作 `Object` 类型而不是作为 `IntransitiveActivity`;它不像任何其它嘟文一样被直接发送,而是被包装在 `Create` 中。
|
||||
- 投票选项使用 `oneOf` 或 `anyOf` 序列化为一个数组。
|
||||
- 此数组中的每个项目都没有 `id`、具有 `Note` 类型,并且具有表示投票选项文本的 `name`。
|
||||
- 此数组中的每个项目还具有一个 `replies` 属性,表示对该特定投票选项的响应。此节点没有 `id`、具有 `Collection` 类型,并且具有表示此选项收到的总票数的 `totalItems` 属性。
|
||||
|
||||
```json
|
||||
{
|
||||
"@context": [
|
||||
"https://www.w3.org/ns/activitystreams",
|
||||
{
|
||||
"votersCount": "http://joinmastodon.org/ns#votersCount"
|
||||
}
|
||||
],
|
||||
"id": "https://mastodon.example/users/alice/statuses/1009947848598745",
|
||||
"type": "Question",
|
||||
"content": "我今天早餐应该吃什么?",
|
||||
"published": "2023-03-05T07:40:13Z",
|
||||
"endTime": "2023-03-06T07:40:13Z",
|
||||
"votersCount": 7,
|
||||
"anyOf": [
|
||||
{
|
||||
"type": "Note",
|
||||
"name": "苹果",
|
||||
"replies": {
|
||||
"type": "Collection",
|
||||
"totalItems": 3
|
||||
}
|
||||
},
|
||||
{
|
||||
"type": "Note",
|
||||
"name": "橙子",
|
||||
"replies": {
|
||||
"type": "Collection",
|
||||
"totalItems": 7
|
||||
}
|
||||
},
|
||||
{
|
||||
"type": "Note",
|
||||
"name": "香蕉",
|
||||
"replies": {
|
||||
"type": "Collection",
|
||||
"totalItems": 6
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
- 投票被序列化为 `Create` 活动,其中 `object` 是一个 `Note`,其 `name` 与投票选项的 `name` 完全匹配。 `Note.inReplyTo` 指向 `Question` 对象的 URI。
|
||||
- 对于多选投票,可能会发送多个活动。如果你之前没有投票选择该选项,则将计入投票。
|
||||
|
||||
```json
|
||||
{
|
||||
"@context": "https://www.w3.org/ns/activitystreams",
|
||||
"id": "https://mastodon.example/users/bob#votes/827163/activity",
|
||||
"to": "https://mastodon.example/users/alice",
|
||||
"actor": "https://mastodon.example/users/bob",
|
||||
"type": "Create",
|
||||
"object": {
|
||||
"id": "https://mastodon.example/users/bob#votes/827163",
|
||||
"type": "Note",
|
||||
"name": "橙子",
|
||||
"attributedTo": "https://mastodon.example/users/bob",
|
||||
"to": "https://mastodon.example/users/alice",
|
||||
"inReplyTo": "https://mastodon.example/users/alice/statuses/1009947848598745"
|
||||
}
|
||||
}
|
||||
```
|
||||
```json
|
||||
{
|
||||
"@context": "https://www.w3.org/ns/activitystreams",
|
||||
"id": "https://mastodon.example/users/bob#votes/827164/activity",
|
||||
"to": "https://mastodon.example/users/alice",
|
||||
"actor": "https://mastodon.example/users/bob",
|
||||
"type": "Create",
|
||||
"object": {
|
||||
"id": "https://mastodon.example/users/bob#votes/827164",
|
||||
"type": "Note",
|
||||
"name": "香蕉",
|
||||
"attributedTo": "https://mastodon.example/users/bob",
|
||||
"to": "https://mastodon.example/users/alice",
|
||||
"inReplyTo": "https://mastodon.example/users/alice/statuses/1009947848598745"
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### 用于寻址和通知的 Mentions {#Mention}
|
||||
|
||||
{{< caption-link url="https://www.w3.org/TR/activitystreams-vocabulary/#microsyntaxes" caption="Activity Vocabulary §5.6 - Mentions, Tags, and Other Common Social Microsyntaxes" >}}
|
||||
|
||||
在 ActivityStreams 术语表中,`Mention` 是 `Link` 的一个子类型,旨在表示 @mentions 的微语法。 `tag` 属性旨在添加对其他 Object 或 Link 的引用。对于 Link 标签,Link 的 `name` 应该是该对象上自然语言属性(`name`、`summary`、`content`)的子字符串。只要找到这样的子字符串,它就可以被转换为指向 `href` 的超链接引用。
|
||||
|
||||
但是,Mastodon 也在某些情况下使用 `Mention` 标签进行寻址。根据 Mention 标签的存在或缺失情况,以及与 `to` 和 `cc` 中显式声明的接收方的比较结果,Mastodon 将计算嘟文的可见性级别。此外,Mastodon 需要 Mention 标签才能生成通知。(要提及的 actor 仍必须被显式包含在 `to` 或 `cc` 中才能接收嘟文。)
|
||||
|
||||
- `public`:公开嘟文在 `to` 中具有 `as:Public` 特殊集合
|
||||
- `unlisted`:未列出的嘟文在 `cc` 中具有 `as:Public` 特殊集合
|
||||
- `private`:仅关注者可见的嘟文在 `to` 或 `cc` 中具有 actor 的关注者集合,但不包括 `as:Public` 魔术集合
|
||||
- `limited`:部分人可见的嘟文在 `to` 或 `cc` 中具有 actor,其中至少有一个未在 `tag` 中被 `Mention`
|
||||
- `direct`:仅提及嘟文在 `to` 或 `cc` 中具有 actor,所有 actor 都在 `tag` 中被 `Mention`
|
||||
|
||||
{{< caption-link url="https://github.com/mastodon/mastodon/blob/main/app/lib/activitypub/activity/create.rb" caption="app/lib/activitypub/activity/create.rb" >}}
|
||||
|
||||
{{< caption-link url="https://github.com/mastodon/mastodon/blob/main/app/lib/activitypub/parser/status_parser.rb" caption="app/lib/activitypub/parser/status_parser.rb" >}}
|
||||
|
||||
## ActivityStreams 未定义的扩展
|
||||
|
||||
以下功能使用 ActivityStreams 未定义的属性和类型定义。
|
||||
|
||||
### 公钥 {#publicKey}
|
||||
|
||||
公钥用于 HTTP 签名和链接数据签名。这是通过 actor 对象上的额外属性 `publicKey` 实现的。有关更多信息,请查看 [安全]({{< relref "spec/security" >}})。
|
||||
|
||||
```json
|
||||
{
|
||||
"@context": [
|
||||
"https://www.w3.org/ns/activitystreams",
|
||||
"https://w3id.org/security/v1"
|
||||
],
|
||||
"id": "https://mastodon.social/users/Gargron",
|
||||
"type": "Person",
|
||||
"publicKey": {
|
||||
"id": "https://mastodon.social/users/Gargron#main-key",
|
||||
"owner": "https://mastodon.social/users/Gargron",
|
||||
"publicKeyPem": "-----BEGIN PUBLIC KEY-----\nMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAvXc4vkECU2/CeuSo1wtn\nFoim94Ne1jBMYxTZ9wm2YTdJq1oiZKif06I2fOqDzY/4q/S9uccrE9Bkajv1dnkO\nVm31QjWlhVpSKynVxEWjVBO5Ienue8gND0xvHIuXf87o61poqjEoepvsQFElA5ym\novljWGSA/jpj7ozygUZhCXtaS2W5AD5tnBQUpcO0lhItYPYTjnmzcc4y2NbJV8hz\n2s2G8qKv8fyimE23gY1XrPJg+cRF+g4PqFXujjlJ7MihD9oqtLGxbu7o1cifTn3x\nBfIdPythWu5b4cujNsB3m3awJjVmx+MHQ9SugkSIYXV0Ina77cTNS0M2PYiH1PFR\nTwIDAQAB\n-----END PUBLIC KEY-----\n"
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### 特色内容 {#featured}
|
||||
|
||||
Mastodon 中被称为“置顶嘟文”的嘟文(或始终在人们的账户顶部显示的嘟文),是使用 actor 对象上的附加属性 `featured` 实现的,该属性指向对象的 `Collection`。
|
||||
|
||||
```json
|
||||
{
|
||||
"@context": [
|
||||
"https://www.w3.org/ns/activitystreams",
|
||||
{
|
||||
"featured": {
|
||||
"@id": "http://joinmastodon.org/ns#featured",
|
||||
"@type": "@id"
|
||||
}
|
||||
}
|
||||
],
|
||||
|
||||
"id": "https://example.com/@alice",
|
||||
"type": "Person",
|
||||
"featured": "https://example.com/@alice/collections/featured"
|
||||
}
|
||||
```
|
||||
|
||||
### 特色话题标签 {#featuredTags}
|
||||
|
||||
Mastodon 允许用户在其账户页上突出显示特定的话题标签,以便于浏览,作为一种可发现性机制。这是通过 actor 对象上的附加属性 `featuredTags` 实现的,该属性专门指向 `Hashtag` 对象的 `Collection`。
|
||||
|
||||
```json
|
||||
{
|
||||
"@context": [
|
||||
"https://www.w3.org/ns/activitystreams",
|
||||
{
|
||||
"featuredTags": {
|
||||
"@id": "http://joinmastodon.org/ns#featuredTags",
|
||||
"@type": "@id"
|
||||
}
|
||||
}
|
||||
],
|
||||
|
||||
"id": "https://example.com/@alice",
|
||||
"type": "Person",
|
||||
"featuredTags": "https://example.com/@alice/collections/tags"
|
||||
}
|
||||
```
|
||||
|
||||
### 账户元数据 {#PropertyValue}
|
||||
|
||||
Mastodon 支持包含名称-值对的任意账户字段。这是通过 actor 对象上的 `attachment` 属性实现的,数组中的对象具有 `PropertyValue` 类型和 `value` 属性,这两者都来自 schema.org 命名空间。
|
||||
|
||||
{{<hint style="warning">}}
|
||||
如以上在列出 [schema.org @context 扩展](#schema) 时所述,Mastodon 当前错误地期望并将术语 `schema` 映射到基础 URI `http://schema.org#` 而不是基础 URI `https://schema.org/`。因此,使用正确的上下文定义的 JSON-LD 处理器将无法正确处理账户字段。
|
||||
{{</hint>}}
|
||||
|
||||
```json
|
||||
{
|
||||
"@context": [
|
||||
"https://www.w3.org/ns/activitystreams",
|
||||
{
|
||||
"schema": "http://schema.org#",
|
||||
"PropertyValue": "schema:PropertyValue",
|
||||
"value": "schema:value"
|
||||
}
|
||||
],
|
||||
"id": "https://mastodon.social/users/Gargron",
|
||||
"type": "Person",
|
||||
"attachment": [
|
||||
{
|
||||
"type": "PropertyValue",
|
||||
"name": "Patreon",
|
||||
"value": "<a href=\"https://www.patreon.com/mastodon\" rel=\"me nofollow noopener noreferrer\" target=\"_blank\"><span class=\"invisible\">https://www.</span><span class=\"\">patreon.com/mastodon</span><span class=\"invisible\"></span}"
|
||||
},
|
||||
{
|
||||
"type": "PropertyValue",
|
||||
"name": "Homepage",
|
||||
"value": "<a href=\"https://zeonfederated.com\" rel=\"me nofollow noopener noreferrer\" target=\"_blank\"><span class=\"invisible\">https://</span><span class=\"\">zeonfederated.com</span><span class=\"invisible\"></span}"
|
||||
}
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
### 身份证明 {{%deprecated%}} {#IdentityProof}
|
||||
|
||||
{{< hint style="warning" >}}
|
||||
由于在 Mastodon 3.5 中删除了 Keybase 支持,因此当前未使用/已弃用此属性:<https://github.com/mastodon/mastodon/pull/17045>
|
||||
{{</hint>}}
|
||||
|
||||
Mastodon 支持与身份提供商集成,以证明账户已链接到某个身份。这是通过 actor 对象上的 `attachment` 属性实现的,数组中的对象具有来自 Mastodon 命名空间的 `IdentityProof` 类型。该对象还包括来自 W3ID 安全术语表命名空间的 `signatureAlgorithm` 和 `signatureValue`。
|
||||
|
||||
```json
|
||||
{
|
||||
"@context": [
|
||||
"https://www.w3.org/ns/activitystreams",
|
||||
"https://w3id.org/security/v1",
|
||||
{
|
||||
"IdentityProof": "http://joinmastodon.org/ns#IdentityProof"
|
||||
}
|
||||
],
|
||||
"id": "https://mastodon.social/users/Gargron",
|
||||
"type": "Person",
|
||||
"attachment": [
|
||||
{
|
||||
"type": "IdentityProof",
|
||||
"name": "gargron",
|
||||
"signatureAlgorithm": "keybase",
|
||||
"signatureValue": "5cfc20c7018f2beefb42a68836da59a792e55daa4d118498c9b1898de7e845690f"
|
||||
}
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
### 可发现标志 {#discoverable}
|
||||
|
||||
Mastodon 允许用户选择加入或退出可发现性功能,例如账户目录。此标志也可用作用户对被包含到外部发现服务中的偏好的指示。如果你要实现此类工具,建议你该属性存在时尊重它设定的值。这是使用映射到账户的对象的附加属性 `discoverable` 实现的。
|
||||
|
||||
```json
|
||||
{
|
||||
"@context": [
|
||||
"https://www.w3.org/ns/activitystreams",
|
||||
{
|
||||
"discoverable": "http://joinmastodon.org/ns#discoverable"
|
||||
}
|
||||
],
|
||||
"id": "https://mastodon.social/users/Gargron",
|
||||
"type": "Person",
|
||||
"discoverable": true
|
||||
}
|
||||
```
|
||||
|
||||
### 可索引标志 {#indexable}
|
||||
|
||||
Mastodon 允许用户选择加入或退出索引功能,例如公开嘟文的全文搜索。如果你要实现此类工具,建议你该属性存在时尊重它设定的值。这是使用映射到账户的对象的附加属性 `indexable` 实现的。
|
||||
|
||||
```json
|
||||
{
|
||||
"@context": [
|
||||
"https://www.w3.org/ns/activitystreams",
|
||||
{
|
||||
"indexable": "http://joinmastodon.org/ns#indexable"
|
||||
}
|
||||
],
|
||||
"id": "https://mastodon.social/users/Gargron",
|
||||
"type": "Person",
|
||||
"indexable": true
|
||||
}
|
||||
```
|
||||
|
||||
### 已被封禁标志 {#suspended}
|
||||
|
||||
Mastodon 举报用户是否在本站被封禁,以便更好地处理这些帐户。 Mastodon 中被封禁的帐户会返回空数据。如果外站帐户被标记为已被封禁,则无法在本站取消封禁。被封禁的帐户可以成为 Update、Undo、Reject 和 Delete 等活动的目标。此功能使用对象的附加属性 `suspended` 实现。
|
||||
|
||||
```json
|
||||
{
|
||||
"@context": [
|
||||
"https://www.w3.org/ns/activitystreams",
|
||||
{
|
||||
"suspended": "http://joinmastodon.org/ns#suspended"
|
||||
}
|
||||
],
|
||||
"id": "https://example.com/@eve",
|
||||
"type": "Person",
|
||||
"suspended": true
|
||||
}
|
||||
```
|
||||
|
||||
### 悼念标志 {#memorial}
|
||||
|
||||
Mastodon 举报用户的账户是否处于悼念状态,以便更好地处理这些帐户。 Mastodon 中的悼念帐户会返回正常数据,但会在顶部显示相应提示,指示该帐户是悼念帐户。此功能使用对象的附加属性 `memorial` 实现。
|
||||
|
||||
```json
|
||||
{
|
||||
"@context": [
|
||||
"https://www.w3.org/ns/activitystreams",
|
||||
{
|
||||
"memorial": "http://joinmastodon.org/ns#memorial"
|
||||
}
|
||||
],
|
||||
"id": "https://example.com/@alice",
|
||||
"type": "Person",
|
||||
"memorial": true
|
||||
}
|
||||
```
|
||||
|
||||
### 话题标签 {#Hashtag}
|
||||
|
||||
与 ActivityStreams 中已定义的 Link 的 `Mention` 子类型类似,Mastodon 将使用 `Hashtag` 作为 Link 的子类型,以便显示嘟文,这些嘟文引用由字符串格式的键标识的某些常见话题。 Hashtag 具有一个 `name`,其中包含 #hashtag 微语法——一个 `#`,后跟一个表示话题的字符串序列。这类似于 @mention 微语法,其中一个 `@` 后跟一个表示资源的字符串序列(Mastodon 的实现预期此资源是一个帐户)。 Mastodon 还会将话题标签规范化为不区分大小写的字符串,执行 ASCII 折叠并删除无效字符。
|
||||
|
||||
{{< caption-link url="https://github.com/mastodon/mastodon/blob/main/app/lib/hashtag_normalizer.rb" caption="app/lib/hashtag_normalizer.rb" >}}
|
||||
|
||||
```json
|
||||
{
|
||||
"@context": [
|
||||
"https://www.w3.org/ns/activitystreams",
|
||||
{
|
||||
"Hashtag": "https://www.w3.org/ns/activitystreams#Hashtag"
|
||||
}
|
||||
],
|
||||
"id": "https://example.com/some-post",
|
||||
"type": "Note",
|
||||
"attributedTo": "https://example.com",
|
||||
"content": "我喜欢 #猫",
|
||||
"tag": [
|
||||
{
|
||||
"type": "Hashtag",
|
||||
"name": "#cats",
|
||||
"href": "https://example.com/tagged/cats"
|
||||
}
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
### 自定义表情 {#Emoji}
|
||||
|
||||
Mastodon 通过包含 `Emoji` 类型的 `tag` 来支持任意表情符号。自定义表情符号的处理方式类似于提及(mention)和话题标签(hashtag),即在自然语言属性(`name`、`summary`、`content`)中找到被标记实体的 `name` 作为子字符串,然后将其链接到某个资源或主题的本地表示。对于表情符号短代码(shortcodes),`name` 会被替换为由 `icon` 属性表示的内联图像的 HTML(其中 `icon.url` 链接到图像资源)。
|
||||
|
||||
```json
|
||||
{
|
||||
"@context": [
|
||||
"https://www.w3.org/ns/activitystreams",
|
||||
{
|
||||
"Emoji": "http://joinmastodon.org/ns#Emoji",
|
||||
}
|
||||
],
|
||||
|
||||
"id": "https://example.com/@alice/hello-world",
|
||||
"type": "Note",
|
||||
"content": "Hello world :kappa:",
|
||||
"tag": [
|
||||
{
|
||||
"id": "https://example.com/emoji/123",
|
||||
"type": "Emoji",
|
||||
"name": ":kappa:",
|
||||
"icon": {
|
||||
"type": "Image",
|
||||
"mediaType": "image/png",
|
||||
"url": "https://example.com/files/kappa.png"
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
### 焦点 {#focalPoint}
|
||||
|
||||
Mastodon 支持在上传的图片上设置焦点,这样无论图片在哪里显示,焦点都会保持在视口内。这是通过在 `Image` 对象上使用一个额外的 `focalPoint` 属性来实现的。该属性是一个包含两个介于 -1.0 和 1.0 之间的浮点数的数组,其中 0,0 代表图像中心,第一个值是 x 坐标(-1.0 是左边缘,+1.0 是右边缘),第二个值是 y 坐标(-1.0 是底边缘,+1.0 是顶边缘)。更多信息请参见 [API 指引 > 焦点]({{< relref "api/guidelines#focal-points" >}})。
|
||||
|
||||
```json
|
||||
{
|
||||
"@context": [
|
||||
"https://www.w3.org/ns/activitystreams",
|
||||
{
|
||||
"focalPoint": {
|
||||
"@container": "@list",
|
||||
"@id": "http://joinmastodon.org/ns#focalPoint"
|
||||
}
|
||||
}
|
||||
],
|
||||
|
||||
"id": "https://example.com/@alice/hello-world",
|
||||
"type": "Note",
|
||||
"content": "此嘟文有一张附图!",
|
||||
"attachment": [
|
||||
{
|
||||
"type": "Image",
|
||||
"mediaType": "image/png",
|
||||
"url": "https://example.com/files/cats.png",
|
||||
"focalPoint": [
|
||||
-0.55,
|
||||
0.43
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
{{< figure src="/assets/focal-points.jpg" caption="演示各种焦点及其坐标。" >}}
|
||||
|
||||
上例中的焦点 (-0.55, 0.43) 对应于图像中心点左侧 55%、上方 43% 的位置。如果进行了任何裁剪,此焦点应在裁剪后的缩略图中保持可见。
|
||||
|
||||
### Blurhash {#blurhash}
|
||||
|
||||
Mastodon 会为附件生成彩色的预览缩略图。这是通过在 `Image` 对象上使用一个额外的 `blurhash` 属性来实现的。该属性是由 [BlurHash 算法](https://blurha.sh) 生成的一个字符串。
|
||||
|
||||
```json
|
||||
{
|
||||
"@context": [
|
||||
"https://www.w3.org/ns/activitystreams",
|
||||
{
|
||||
"blurhash": "http://joinmastodon.org/ns#blurhash"
|
||||
}
|
||||
],
|
||||
|
||||
"id": "https://example.com/@alice/hello-world",
|
||||
"type": "Note",
|
||||
"content": "此嘟文有一张附图!",
|
||||
"attachment": [
|
||||
{
|
||||
"type": "Image",
|
||||
"mediaType": "image/png",
|
||||
"url": "https://example.com/files/cats.png",
|
||||
"blurhash": "UBL_:rOpGG-oBUNG,qRj2so|=eE1w^n4S5NH"
|
||||
}
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
### 敏感内容 {#sensitive}
|
||||
|
||||
Mastodon 使用 `as:sensitive` 扩展属性来标记某些嘟文为敏感内容。当一条嘟文被标记为敏感时,其附加的任何媒体都将默认隐藏,并且如果存在 `summary`,嘟文的 `content` 将被折叠在该摘要后面。在 Mastodon 中,这被称为**内容警告**。
|
||||
|
||||
## 其他功能
|
||||
|
||||
### 安全模式 {#secure-mode}
|
||||
|
||||
当 Mastodon 实例在安全模式下运行时,所有对其发起的跨站 HTTP 请求都必须进行签名(换句话说,即使是对公开资源的 `GET` 请求也需要签名)。这样,Mastodon 实例可以选择拒绝来自其已阻止的实例的请求,避免“泄露”公共信息。Mastodon 本身使用一个专用的系统行为体(system actor)来签名此类 HTTP 请求。有关 HTTP 签名的更多详细信息,请查看 [安全]({{< relref "spec/security" >}})。
|
||||
|
||||
安全模式是构建“有限联合模式”的基础。处于有限联合模式下的 Mastodon 实例将只与其管理员明确允许的实例进行联合,并拒绝所有其他请求。
|
||||
|
||||
### 关注者同步机制
|
||||
|
||||
Mastodon 具有“仅关注者可见”嘟文的概念,但目前关注者集合的扩展是在接收方处理,而不是在发送方处理(即,不使用显式寻址)。因此,需要一种机制来检测同步问题并进行纠正。该机制必须能够处理部分关注者集合,而不是完整的集合(完整集合可能不是公开信息)。此集合之所以是部分的,是因为它只包含来自特定实例的关注者,但它必须包含所有这些关注者。如果某个关注者从集合中被遗漏,将导致该关注关系被断开。
|
||||
|
||||
在向外站用户递送消息时,会附加一个可选的 `Collection-Synchronization` HTTP 标头,其语法与 `Signature` 标头相同,包含以下属性:
|
||||
|
||||
- `collectionId` = 必须是发送者的 `followers` 集合
|
||||
- `url` = 指向一个部分集合的 URL,该集合包含发送者所有位于接收方实例上的关注者的标识符。必须与行为体(actor)本身位于同一域,并且应该只能通过来自接收方实例的签名查询进行访问
|
||||
- `digest` = 部分集合中每个标识符的 SHA256 摘要进行异或运算后得到的十六进制表示
|
||||
|
||||
示例:
|
||||
|
||||
```http
|
||||
POST https://mastodon.social/users/foo/inbox HTTP/1.1
|
||||
Collection-Synchronization:
|
||||
collectionId="https://social.sitedethib.com/users/Thib/followers",
|
||||
url="https://social.sitedethib.com/users/Thib/followers_synchronization",
|
||||
digest="b08ab6951c7d6cc2b91e17ebd9557da7fae02489728e9332fcb3a97748244d50"
|
||||
```
|
||||
|
||||
当外站用户尝试 GET 部分集合 `url` 时,此请求必须使用 HTTP 签名进行签名。示例:
|
||||
|
||||
```http
|
||||
GET https://social.sitedethib.com/users/Thib/followers_synchronization HTTP/1.1
|
||||
Signature: ... # 来自 mastodon.social 上某个账户的签名
|
||||
|
||||
{
|
||||
"@context": "https://www.w3.org/ns/activitystreams",
|
||||
"id": "https://social.sitedethib.com/users/Thib/followers?domain=mastodon.social",
|
||||
"type": "OrderedCollection",
|
||||
"orderedItems": [
|
||||
"https://mastodon.social/users/Gargron"
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
{{< translation-status-zh-cn raw_title="ActivityPub" raw_link="/spec/activitypub/" last_translation_time="2025-04-06" raw_commit="5e2b739ee193896bea937addc2843146ea0bc870">}}
|
31
content/zh-cn/spec/bearcaps.md
Normal file
31
content/zh-cn/spec/bearcaps.md
Normal file
|
@ -0,0 +1,31 @@
|
|||
---
|
||||
title: Bearcaps
|
||||
description: 一种将 URL 与访问它们所需的 Bearer 令牌结合起来的 URI 方案。
|
||||
menu:
|
||||
docs:
|
||||
weight: 60
|
||||
parent: spec
|
||||
---
|
||||
|
||||
## 什么是 Bearcaps? {#intro}
|
||||
|
||||
在某些情况下,资源可能不是公开可用的,可能需要令牌才能成功获取。这通常通过使用包含 `Bearer` 令牌的 HTTP `Authorization` 标头来完成,如下所示:
|
||||
|
||||
```http
|
||||
GET https://example.com/foo
|
||||
Authorization: Bearer <token>
|
||||
```
|
||||
|
||||
Bearcaps 提供了一种链接到包含令牌的资源的方法,如下所示:
|
||||
|
||||
```
|
||||
bear:?t=<token>&u=https://example.com/foo'
|
||||
```
|
||||
|
||||
要将 bearcap 转换为 HTTP 请求,请向 `u` 参数发出请求,并将 `t` 参数作为 `Bearer` 令牌附加在 `Authorization` 标头中。
|
||||
|
||||
## Bearcaps 在 Mastodon 中如何使用? {#usage}
|
||||
|
||||
从 v3.3.0 开始,Mastodon 支持在接收到的 Activity 中解引用 bearcaps。目前 Bearcaps 尚未用于发送任何 Activity。
|
||||
|
||||
{{< translation-status-zh-cn raw_title="Bearcaps" raw_link="/spec/bearcaps/" last_translation_time="2025-04-06" raw_commit="5e2b739ee193896bea937addc2843146ea0bc870">}}
|
103
content/zh-cn/spec/microformats.md
Normal file
103
content/zh-cn/spec/microformats.md
Normal file
|
@ -0,0 +1,103 @@
|
|||
---
|
||||
title: Microformats
|
||||
description: 一种开放的数据格式,利用 CSS 类来结构化你已有的 HTML。
|
||||
menu:
|
||||
docs:
|
||||
weight: 40
|
||||
parent: spec
|
||||
---
|
||||
|
||||
{{< hint style="info" >}}
|
||||
从 v4.0.0 版本开始,嘟文和账户的 HTML 永久链接已被弃用并从 Mastodon 中移除。因此,Microformats 当前未在 Mastodon 中使用,也未由其生成。
|
||||
{{< /hint >}}
|
||||
|
||||
## 什么是 microformats? {#intro}
|
||||
|
||||
[Microformats 2.0](https://microformats.io/) 是一种标准,用于将元数据直接嵌入到 HTML 文档中。无需使用 API 进行只读目的,可以通过解析网页中的特定 CSS 类来提取信息。你只需查看页面即可获取这些信息,而不必单独从 API 请求相同的信息。使用 microformats 类可以对给定网页中的数据进行语义解析,并可用于生成 feed、卡片或数据的表示形式。
|
||||
|
||||
## Microformats 类 {#classes}
|
||||
|
||||
所有 microformats 类都使用前缀。前缀表示元素的类型,与层次结构无关。以下是 Mastodon 代码库中使用的 microformats 类。
|
||||
|
||||
### 根元素(`h-*`) {#h}
|
||||
|
||||
#### `h-feed` {#h-feed}
|
||||
|
||||
表示一个条目流。附加到账户的嘟文。也附加到详细嘟文视图中的父主题。
|
||||
|
||||
#### `h-entry` {#h-entry}
|
||||
|
||||
表示情景性的或带有时间戳的在线内容。附加到嘟文。
|
||||
|
||||
#### `h-cite` {#h-cite}
|
||||
|
||||
表示对另一个在线出版物的引用。附加到转嘟。也附加到嘟文详情视图中嘟文串内的其他嘟文。
|
||||
|
||||
#### `h-card` {#h-card}
|
||||
|
||||
表示一个人或组织。附加到昵称、用户名和头像的容器。也附加到提及。
|
||||
|
||||
### 纯文本属性(`p-*`) {#p}
|
||||
|
||||
#### `p-author` {#p-author}
|
||||
|
||||
在 `h-entry` 或 `h-cite` 中,表示条目的作者,并附加到昵称、用户名和头像的容器。
|
||||
|
||||
#### `p-name` {#p-name}
|
||||
|
||||
在 `h-feed` 中,表示 feed 的标题。附加到具有 `value` 属性的 `data` 元素。
|
||||
在 `h-entry` 或 `h-cite` 中,表示条目的标题。在 Mastodon 中未使用。
|
||||
在 `h-card` 中,表示个人或组织的纯文本名称。附加到昵称。
|
||||
|
||||
#### `p-in-reply-to` {#p-in-reply-to}
|
||||
|
||||
在嘟文详情的 `h-entry` 中,表示作为直接上级的嘟文。
|
||||
|
||||
#### `p-repost-of` {#p-repost-of}
|
||||
|
||||
在嘟文详情的 `h-entry` 中,表示作为转嘟且也是直接上级嘟文的嘟文。目前未使用,因为不能回复转嘟。
|
||||
|
||||
#### `p-comment` {#p-comment}
|
||||
|
||||
在嘟文详情的 `h-entry` 中,表示作为直接下级的嘟文。
|
||||
|
||||
### URL 属性(`u-*`) {#u}
|
||||
|
||||
#### `u-photo` {#u-photo}
|
||||
|
||||
在 `h-card` 中,表示账户图片。附加到头像图像。
|
||||
|
||||
#### `u-uid` {#u-uid}
|
||||
|
||||
在 `h-entry` 或 `h-cite` 中,表示通用唯一标识符。附加到时间戳链接。
|
||||
|
||||
#### `u-url` {#u-url}
|
||||
|
||||
在 `h-entry` 或 `h-cite` 中,表示嘟文永久链接。附加到时间戳链接。
|
||||
在 `h-card` 中,表示账户永久链接。附加到昵称链接。
|
||||
|
||||
### 日期时间属性(`dt-*`) {#dt}
|
||||
|
||||
#### `dt-published` {#dt-published}
|
||||
|
||||
在 `h-entry` 或 `h-cite` 中,表示嘟文发布的日期和时间。附加到具有 `value` 属性的 `data` 元素。
|
||||
|
||||
### 元素树(`e-*`) {#e}
|
||||
|
||||
#### `e-content` {#e-content}
|
||||
|
||||
在 `h-entry` 或 `h-cite` 中,表示嘟文的内容。附加到嘟文内容。
|
||||
|
||||
## 附加类 {#mastodon}
|
||||
|
||||
这些元素由 Mastodon 附加,用于解析元数据,但从技术上讲不属于 Microformats 术语表的一部分。
|
||||
|
||||
#### `mention` {#mention}
|
||||
|
||||
表示应在应用内打开该链接,并带有来自 API 的关联提及数据。
|
||||
|
||||
#### `hashtag` {#hashtag}
|
||||
|
||||
表示应在应用内打开该链接,并带有来自 API 的关联话题标签数据。
|
||||
|
||||
{{< translation-status-zh-cn raw_title="Microformats" raw_link="/spec/microformats/" last_translation_time="2025-04-06" raw_commit="5e2b739ee193896bea937addc2843146ea0bc870">}}
|
90
content/zh-cn/spec/oauth.md
Normal file
90
content/zh-cn/spec/oauth.md
Normal file
|
@ -0,0 +1,90 @@
|
|||
---
|
||||
title: OAuth
|
||||
description: 一种基于令牌的互联网认证和授权开放标准
|
||||
menu:
|
||||
docs:
|
||||
weight: 50
|
||||
parent: spec
|
||||
---
|
||||
|
||||
## 什么是 OAuth? {#intro}
|
||||
|
||||
Mastodon API 有许多方法需要客户端的身份验证或用户的授权。这是通过 OAuth 2.0 完成的,OAuth 2.0 是 [RFC 6749](https://tools.ietf.org/html/rfc6749) 中描述的一种授权框架,它允许第三方应用程序通过使用标准化的授权流程,代表资源所有者获得对 HTTP 服务的有限访问权限,该流程生成一个客户端访问令牌,用于 HTTP 请求。
|
||||
|
||||
要获取 Mastodon 站点的 OAuth 令牌,请确保允许用户在登录前指定要连接的域名。使用该域名[获取客户端 ID/密钥]({{< relref "methods/apps#create" >}}),然后[继续执行正常的 OAuth 2 流程]({{< relref "methods/oauth" >}})。
|
||||
|
||||
## OAuth 2 客户端类型 {#client-types}
|
||||
|
||||
OAuth 2 根据客户端与授权服务器安全认证的能力(即,维护客户端凭据机密性的能力)定义了两种客户端类型:`confidential`(机密)和 `public`(公共)。机密客户端可以使用[客户端凭据授权流程]({{<relref "client/token#flow" >}}),而公共客户端则不能。
|
||||
|
||||
目前,Mastodon 仅支持机密客户端,但[正在进行相关工作](https://github.com/mastodon/mastodon/pull/30329)以添加对公共客户端的支持。
|
||||
|
||||
## 已实现的 OAuth 2 端点 {#implementation}
|
||||
|
||||
以下描述摘自 [Doorkeeper 文档](https://github.com/doorkeeper-gem/doorkeeper/wiki/API-endpoint-descriptions-and-examples)。Mastodon 使用 Doorkeeper 来实现 OAuth 2。有关如何使用这些端点的更多信息,请查看 [OAuth 的 API 文档]({{< relref "methods/oauth" >}})。
|
||||
|
||||
{{< caption-link url="https://github.com/mastodon/mastodon/blob/main/config/initializers/doorkeeper.rb" caption="Doorkeeper 配置初始化器" >}}
|
||||
|
||||
### 授权服务器元数据端点 ([RFC 8414](https://www.rfc-editor.org/rfc/rfc8414.html)) {#authorization-server-metadata}
|
||||
|
||||
返回一个 JSON 文档,表示 Mastodon 中 OAuth 2 服务器的配置。信息包括注册[应用]({{% relref "methods/apps#create" %}})或请求[访问令牌]({{% relref "methods/oauth#token" %}})时可用的 `scopes`、请求访问令牌时可以使用的 `grant_types_supported`,以及与 Mastodon OAuth 服务器交互的各种端点,例如 `authorization_endpoint` 和 `token_endpoint`。
|
||||
|
||||
**版本历史:**\
|
||||
4.3.0 - 添加
|
||||
|
||||
{{< page-relref ref="methods/oauth#authorization-server-metadata" caption="GET /.well-known/oauth-authorization-server" >}}
|
||||
|
||||
### 动态客户端注册端点 ([RFC 7591](https://www.rfc-editor.org/rfc/rfc7591.html)) {#dynamic-client-registration}
|
||||
|
||||
目前,Mastodon 不支持动态客户端注册协议,但支持用于注册 OAuth 应用程序的专有端点。
|
||||
|
||||
{{< page-relref ref="methods/apps#create" caption="POST /api/v1/apps" >}}
|
||||
|
||||
### 授权端点 ([RFC 6749 Section 3.1](https://www.rfc-editor.org/rfc/rfc6749.html#section-3.1)) {#authorization}
|
||||
|
||||
向用户显示授权表单。如果获得批准,将创建并返回授权码,然后重定向到所需的 `redirect_uri`,如果请求了 `urn:ietf:wg:oauth:2.0:oob`,则直接显示授权码。
|
||||
|
||||
{{< page-relref ref="methods/oauth#authorize" caption="GET /oauth/authorize" >}}
|
||||
|
||||
### 令牌获取端点 ([RFC 6749 Section 3.2](https://www.rfc-editor.org/rfc/rfc6749.html#section-3.2)) {#token}
|
||||
|
||||
获取访问令牌。Mastodon 支持以下 OAuth 2 流程:
|
||||
|
||||
授权流程
|
||||
: 供最终用户使用
|
||||
|
||||
客户端凭据流程
|
||||
: 供不代表用户操作的应用程序使用
|
||||
|
||||
Mastodon 历史上一直支持密码授权流程,但由于安全问题,OAuth 2 规范作者[不建议使用](https://datatracker.ietf.org/doc/html/draft-ietf-oauth-security-topics#name-resource-owner-password-cre)密码授权流程,并且该流程已从 Mastodon 的未来版本中删除。相反,建议你为该用户创建一个 OAuth 应用程序,并使用生成的访问令牌与 API 交互。
|
||||
|
||||
{{< page-relref ref="methods/oauth#token" caption="POST /oauth/token" >}}
|
||||
|
||||
### 令牌撤销端点 ([RFC 7009 Section 2](https://www.rfc-editor.org/rfc/rfc7009.html#section-2)) {#revoke}
|
||||
|
||||
在此处使用客户端凭据来撤销访问令牌。
|
||||
|
||||
{{< page-relref ref="methods/oauth#revoke" caption="POST /oauth/revoke" >}}
|
||||
|
||||
## OAuth 2 安全注意事项
|
||||
|
||||
### 授权码交换证明密钥 (PKCE) {#pkce}
|
||||
|
||||
在执行 OAuth 2 [授权流程]({{< relref ref="methods/oauth#authorize" >}})时,你可以采用一种额外的安全机制,以提高用户重定向回你的应用程序时授权码的安全性。这被称为授权码交换证明密钥,或 PKCE(发音为 pixie),Mastodon 4.3.0 及更高版本支持此功能。
|
||||
|
||||
我们建议,按照 [OAuth 2 安全最佳实践](https://www.ietf.org/archive/id/draft-ietf-oauth-security-topics-27.html#name-pkce),将 PKCE 与授权流程一起用于机密客户端和公共客户端。
|
||||
|
||||
{{< caption-link url="https://oauth.net/2/pkce/" caption="在 OAuth.net 网站上了解更多关于 PKCE 的信息" >}}
|
||||
|
||||
### 状态参数 {#state-parameter}
|
||||
|
||||
在执行 OAuth 2 [授权流程]({{< relref ref="methods/oauth#authorize" >}})时,你可以使用授权端点的 [`state` 参数](https://datatracker.ietf.org/doc/html/rfc6749#section-4.1.1) 来防止混淆和跨站请求伪造攻击。完成 OAuth 授权流程后,此参数将通过重定向 URI 原样返回到你的服务器。
|
||||
|
||||
还可以使用此参数通过授权流程将任意信息传递到你的服务器。如果你使用 `state` 参数,建议你在完成授权流程(即,将授权码交换为访问令牌)之前比较或验证状态值。
|
||||
|
||||
## 常见问题 {#gotchas}
|
||||
|
||||
- 使用 Mastodon 的 REST API 注册应用时,有一个 `scopes` 参数。当与 OAuth 端点交互时,你必须改用 `scope` 参数,并且此参数的值必须是注册应用时指定的 `scopes` 的子集。你不能包含原始集合中没有的任何内容。
|
||||
- 使用 Mastodon 的 REST API 注册应用时,有一个 `redirect_uris` 参数。当与 OAuth 端点交互时,你必须改用 `redirect_uri` 参数,并且此参数的值必须是注册应用时指定的 `redirect_uris` 之一。
|
||||
|
||||
{{< translation-status-zh-cn raw_title="OAuth" raw_link="/spec/oauth/" last_translation_time="2025-04-06" raw_commit="5e2b739ee193896bea937addc2843146ea0bc870">}}
|
170
content/zh-cn/spec/security.md
Normal file
170
content/zh-cn/spec/security.md
Normal file
|
@ -0,0 +1,170 @@
|
|||
---
|
||||
title: 安全性
|
||||
description: 基于 HTTP 和 JSON-LD 的公钥加密与支持的签名方案。
|
||||
menu:
|
||||
docs:
|
||||
weight: 30
|
||||
parent: spec
|
||||
---
|
||||
|
||||
## HTTP 签名 {#http}
|
||||
|
||||
{{< caption-link url="https://github.com/mastodon/mastodon/blob/main/app/lib/request.rb" caption="app/lib/request.rb" >}}
|
||||
|
||||
[HTTP 签名](https://datatracker.ietf.org/doc/html/draft-cavage-http-signatures) 是一项通过在 HTTP 请求中使用 `Signature:` 标头来签署 HTTP 消息的规范。为了验证接收到的任何活动是否由生成该活动的行为体所创作,Mastodon 要求使用 HTTP 签名。启用安全模式后,所有 GET 请求也需要 HTTP 签名。
|
||||
|
||||
对于任何传入 Mastodon 的 HTTP 请求,都应附加 Signature 头:
|
||||
|
||||
```http
|
||||
Signature: keyId="https://my.example.com/actor#main-key",headers="(request-target) host date",signature="Y2FiYW...IxNGRiZDk4ZA=="
|
||||
```
|
||||
|
||||
`Signature:` 头的三个部分可以分解如下:
|
||||
|
||||
```http
|
||||
Signature:
|
||||
keyId="https://my.example.com/actor#main-key",
|
||||
headers="(request-target) host date",
|
||||
signature="Y2FiYW...IxNGRiZDk4ZA=="
|
||||
```
|
||||
|
||||
`keyId` 应与行为体和用于生成 `signature` 的密钥相对应,`signature` 的值等于 `headers` 中的所有参数连接在一起并由密钥签名,然后进行 Base64 编码后得到的值。有关行为体密钥的更多信息,请查看 [ActivityPub > 公钥]({{< relref "activitypub#publicKey" >}})。一个示例密钥如下所示:
|
||||
|
||||
```json
|
||||
"publicKey": {
|
||||
"id": "https://my.example.com/actor#main-key",
|
||||
"owner": "https://my.example.com/actor",
|
||||
"publicKeyPem": "-----BEGIN PUBLIC KEY-----\nMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAvXc4vkECU2/CeuSo1wtn\nFoim94Ne1jBMYxTZ9wm2YTdJq1oiZKif06I2fOqDzY/4q/S9uccrE9Bkajv1dnkO\nVm31QjWlhVpSKynVxEWjVBO5Ienue8gND0xvHIuXf87o61poqjEoepvsQFElA5ym\novljWGSA/jpj7ozygUZhCXtaS2W5AD5tnBQUpcO0lhItYPYTjnmzcc4y2NbJV8hz\n2s2G8qKv8fyimE23gY1XrPJg+cRF+g4PqFXujjlJ7MihD9oqtLGxbu7o1cifTn3x\nBfIdPythWu5b4cujNsB3m3awJjVmx+MHQ9SugkSIYXV0Ina77cTNS0M2PYiH1PFR\nTwIDAQAB\n-----END PUBLIC KEY-----\n"
|
||||
},
|
||||
```
|
||||
|
||||
另请查看:[https://blog.joinmastodon.org/2018/07/how-to-make-friends-and-verify-requests/](https://blog.joinmastodon.org/2018/07/how-to-make-friends-and-verify-requests/)
|
||||
|
||||
### 创建 HTTP 签名 {#http-sign}
|
||||
|
||||
要创建 HTTP 签名,你必须定义要执行哈希和签名的标头。例如,考虑以下 GET 请求:
|
||||
|
||||
```http
|
||||
GET /users/username/outbox HTTP/1.1
|
||||
Host: mastodon.example
|
||||
Date: 18 Dec 2019 10:08:46 GMT
|
||||
Accept: application/ld+json; profile="https://www.w3.org/ns/activitystreams"
|
||||
```
|
||||
|
||||
签名字符串使用 `headers` 中定义的 HTTP 标头的值构建,并用换行符连接。通常,你希望包括请求目标,以及主机和日期。如果没有提供 `Date:` 标头,Mastodon 会进行假定。对于上面的 GET 请求,为了使用 `headers="(request-target) host date"` 生成 `Signature:`,我们将生成以下字符串:
|
||||
|
||||
```text
|
||||
(request-target): get /users/username/outbox
|
||||
host: mastodon.example
|
||||
date: 18 Dec 2019 10:08:46 GMT
|
||||
```
|
||||
|
||||
请注意,我们不关心 `Accept:` 标头,因为我们不会在 `headers` 中指定它。
|
||||
|
||||
然后,使用 RSA-SHA256(使用 SHA-256 的 RSASSA-PKCS1-v1_5)对签名字符串执行哈希处理,并使用行为体的私钥进行签名。结果作为 `signature` 附加在 `Signature:` 头中。最终的请求如下所示:
|
||||
|
||||
```http
|
||||
GET /users/username/inbox HTTP/1.1
|
||||
Host: mastodon.example
|
||||
Date: 18 Dec 2019 10:08:46 GMT
|
||||
Accept: application/ld+json; profile="https://www.w3.org/ns/activitystreams"
|
||||
Signature: keyId="https://my.example.com/actor#main-key",headers="(request-target) host date",signature="Y2FiYW...IxNGRiZDk4ZA=="
|
||||
```
|
||||
|
||||
此请求在功能上等同于说 `https://my.example.com/actor` 正在请求 `https://mastodon.example/users/username/inbox`,并通过使用链接到 `keyId` 的私钥对 `(request-target)`、`Host:` 和 `Date:` 进行签名来证明他们发送了此请求,从而生成提供的 `signature`。
|
||||
|
||||
#### 签名 POST 请求和摘要标头 {#digest}
|
||||
|
||||
在向 Mastodon 发出 POST 请求时,你必须计算请求正文的 RSA-SHA256 摘要哈希,并将此哈希(以 base64 编码)包含在 `Digest:` 标头中。`Digest:` 标头也必须包含在 `Signature:` 标头的 `headers` 参数中。例如:
|
||||
|
||||
```http
|
||||
POST /users/username/inbox HTTP/1.1
|
||||
HOST: mastodon.example
|
||||
Date: 18 Dec 2019 10:08:46 GMT
|
||||
Digest: sha-256=hcK0GZB1BM4R0eenYrj9clYBuyXs/lemt5iWRYmIX0A=
|
||||
Signature: keyId="https://my.example.com/actor#main-key",headers="(request-target) host date digest",signature="Y2FiYW...IxNGRiZDk4ZA=="
|
||||
Content-Type: application/ld+json; profile="https://www.w3.org/ns/activitystreams"
|
||||
|
||||
{
|
||||
"@context": "https://www.w3.org/ns/activitystreams",
|
||||
"actor": "https://my.example.com/actor",
|
||||
"type": "Create",
|
||||
"object": {
|
||||
"type": "Note",
|
||||
"content": "Hello!"
|
||||
},
|
||||
"to": "https://mastodon.example/users/username"
|
||||
}
|
||||
```
|
||||
|
||||
### 验证 HTTP 签名 {#http-verify}
|
||||
|
||||
{{< caption-link url="https://github.com/mastodon/mastodon/blob/main/app/controllers/concerns/signature_verification.rb" caption="app/controllers/concerns/signature_verification.rb" >}}
|
||||
|
||||
考虑以下请求:
|
||||
|
||||
```http
|
||||
POST /users/username/inbox HTTP/1.1
|
||||
Host: mastodon.example
|
||||
Date: 18 Dec 2019 10:08:46 GMT
|
||||
Digest: e37e179c75071a291f90a5fd4f848da87b491f1282f7bb8509ef2115b81ee0f4
|
||||
Signature: keyId="https://my.example.com/actor#main-key",headers="(request-target) host date digest",signature="Y2FiYW...IxNGRiZDk4ZA=="
|
||||
Content-Type: application/ld+json; profile="https://www.w3.org/ns/activitystreams"
|
||||
|
||||
{
|
||||
"@context": "https://www.w3.org/ns/activitystreams",
|
||||
"actor": "https://my.example.com/actor",
|
||||
"type": "Create",
|
||||
"object": {
|
||||
"type": "Note",
|
||||
"content": "Hello!"
|
||||
}
|
||||
"to": "https://mastodon.example/users/username"
|
||||
}
|
||||
```
|
||||
|
||||
Mastodon 使用以下算法验证签名:
|
||||
|
||||
* 将 `Signature:` 分解为单独的参数。
|
||||
* 从 `headers` 的值构造签名字符串。
|
||||
* 获取 `keyId` 并解析为行为体的 `publicKey`。
|
||||
* 对签名字符串执行 RSA-SHA256 哈希处理,并将其与用 `publicKey[publicKeyPem]` 解密的 Base64 解码后的 `signature` 进行比较。
|
||||
* 使用 `Date:` 标头检查已签名的请求是否在过去 12 小时内发出。
|
||||
|
||||
## 关联数据签名 {#ld}
|
||||
|
||||
{{< caption-link url="https://github.com/mastodon/mastodon/blob/main/app/lib/activitypub/linked_data_signature.rb" caption="app/lib/activitypub/linked_data_signature.rb" >}}
|
||||
|
||||
{{< hint style="warning" >}}
|
||||
由于在草案阶段和规范最终确定阶段之间 JSON-LD `@context` 发生了更改,Mastodon 当前的 LD 签名实现已过时。Mastodon 期望 `type` 为 `RsaSignature2017`,而后来的草案通过命名空间 `https://w3id.org/security/v2` 定义了 `RsaSignature2018`。此外,整个 LD 签名规范已被 [可验证凭据完整性规范 1.0](https://w3c.github.io/vc-data-integrity/) 取代,该规范与早期 LD 签名规范在很大程度上不兼容。因此,不建议实现对 LD 签名的支持。
|
||||
{{< /hint >}}
|
||||
|
||||
[关联数据签名 1.0](https://web.archive.org/web/20170923124140/https://w3c-dvcg.github.io/ld-signatures/) 是一项将加密签名附加到 JSON-LD 文档的草案规范。LD 签名在 Mastodon 中使用不广泛,但在以下情况下使用:
|
||||
|
||||
- 运行 [自毁]({{< relref "admin/tootctl#tootctl-self-destruct" >}}) 序列以将 Delete 活动发送到所有已知联合实例时,有效负载将使用 LD 签名,因为 HTTP 签名将不可用。接收服务器将通过针对本地缓存的行为体密钥验证签名来处理签名,因为 HTTP 服务器将不再托管旧的行为体信息。
|
||||
- 接受来自中继的活动时。公共活动可以选择使用 LD 进行签名并发送给中继,这样任何订阅中继的服务器都不必手动从源重新获取活动。这可以防止潜在的无限多服务器尝试从你的实例加载嘟文。
|
||||
|
||||
### 创建 LD 签名 {#ld-sign}
|
||||
|
||||
要创建签名,Mastodon 使用附加到位于 `https://mastodon.example/users/username#main-key` 的行为体的密钥对。然后,它创建文档的 RSA-SHA256 哈希,使用密钥对对其进行签名,并对生成的输出进行 Base64 严格编码以派生 `signatureValue`。以下哈希将被合并到 JSON-LD 文档中:
|
||||
|
||||
```json
|
||||
"signature": {
|
||||
"type": "RsaSignature2017",
|
||||
"creator": "https://mastodon.example/users/username#main-key",
|
||||
"created": "2019-12-08T03:48:33.901Z",
|
||||
"signatureValue": "s69F3mfddd99dGjmvjdjjs81e12jn121Gkm1"
|
||||
}
|
||||
```
|
||||
|
||||
### 验证 LD 签名 {#ld-verify}
|
||||
|
||||
要验证签名,Mastodon 使用以下算法:
|
||||
|
||||
* 确保 `signature` 存在且为哈希。
|
||||
* 确保 `signature[type]` 为 `RsaSignature2017`。
|
||||
* 获取 `signature[creator]` URI。确保创建者存在。
|
||||
* 从 `signature` 中剥离 `type`、`id` 和 `signatureValue`,只留下 `signature[creator]` 和 `signature[created]`。
|
||||
* 对 `signatureValue` 进行 Base64 解码,并根据 `signature[creator]` 中的公钥对其进行验证。
|
||||
|
||||
{{< translation-status-zh-cn raw_title="Security" raw_link="/spec/security/" last_translation_time="2025-04-06" raw_commit="5e2b739ee193896bea937addc2843146ea0bc870">}}
|
111
content/zh-cn/spec/webfinger.md
Normal file
111
content/zh-cn/spec/webfinger.md
Normal file
|
@ -0,0 +1,111 @@
|
|||
---
|
||||
title: WebFinger
|
||||
description: 将 `user@domain` mentions 转换为 Actor 账户 URI。
|
||||
menu:
|
||||
docs:
|
||||
weight: 20
|
||||
parent: spec
|
||||
---
|
||||
|
||||
## 什么是 WebFinger,为何使用它? {#intro}
|
||||
|
||||
在 Mastodon 中,账户可以托管在与你的账户相同的站点,也可以托管在一个完全不同的站点。同一个用户名可能会在不同的域名上使用。因此,一个完整的 Mastodon 用户 mentions 由用户名和域名两部分组成,格式为 `@username@domain`。实际上,`@user@example.com` 与 `@user@example.org` 是不同的。如果不包含域名,Mastodon 会尝试查找名为 `@username` 的本地用户。但是,为了通过 ActivityPub 将内容递送给某人,仅有 `@username@domain` mentions 是不够的 —— **必须首先将 mentions 转换为 HTTPS URI**,这样才能找到远程 Actor 的收件箱和发件箱。
|
||||
|
||||
于是就有了 WebFinger。如 [RFC 7033](https://tools.ietf.org/html/rfc7033) 所述,WebFinger 是一项规范,它定义了**一种在仅知道特定服务器上的 URI 的情况下解析资源链接的方法**。这使得任何人都能在无需事先知道资源确切地址的情况下查找资源的位置;例如,可以通过电子邮件或电话号码进行查找。此查找请求将被发往 `/.well-known/webfinger` 端点,并附带一个 `resource` 查询参数。Mastodon 使用的资源 URI 是 [RFC 7565](https://tools.ietf.org/html/rfc7565) 中描述的 `acct:` URI,其包含了托管在特定域名上的账户的用户名。
|
||||
|
||||
{{< hint style="danger" >}}
|
||||
**由于 Mastodon 严重依赖 mentions 来定位其他账户,因此要与 Mastodon 完全互操作,WebFinger 是必需的。** 用户通常可以通过搜索直接的 HTTPS URI(如果知道对应的 URI 的话)或 `username@domain` 地址来加载账户,但 Mastodon 的内部逻辑几乎完全依赖于 `acct:` URI 或 `username@domain` 表示形式。如果一个 ActivityPub 实现不支持 WebFinger,那么搜索任何对象或账户都会失败,因为其作者无法被转换为本地数据库中的用户。
|
||||
{{< /hint >}}
|
||||
|
||||
## WebFinger 流程示例 {#example}
|
||||
|
||||
假设我们想要查找托管在 `mastodon.social` 网站上的用户 `@Gargron`。
|
||||
|
||||
只需向该域名的 `/.well-known/webfinger` 端点发起请求,并将 `resource` 查询参数设置为 `acct:` URI 即可。
|
||||
|
||||
{{< code title="https://mastodon.social/.well-known/webfinger?resource=acct:gargron@mastodon.social" >}}
|
||||
```json
|
||||
{
|
||||
"subject": "acct:Gargron@mastodon.social",
|
||||
"aliases": [
|
||||
"https://mastodon.social/@Gargron",
|
||||
"https://mastodon.social/users/Gargron"
|
||||
],
|
||||
"links": [
|
||||
{
|
||||
"rel": "http://webfinger.net/rel/profile-page",
|
||||
"type": "text/html",
|
||||
"href": "https://mastodon.social/@Gargron"
|
||||
},
|
||||
{
|
||||
"rel": "self",
|
||||
"type": "application/activity+json",
|
||||
"href": "https://mastodon.social/users/Gargron"
|
||||
},
|
||||
{
|
||||
"rel": "http://ostatus.org/schema/1.0/subscribe",
|
||||
"template": "https://mastodon.social/authorize_interaction?uri={uri}"
|
||||
}
|
||||
]
|
||||
}
|
||||
```
|
||||
{{< /code >}}
|
||||
|
||||
您可以解析此 JSON 响应,以查找具有您所需类型的链接。对于 ActivityPub 的 `id`,我们特别关注查找 `application/activity+json` 类型。
|
||||
|
||||
这样,我们就将 `@Gargron@mastodon.social` 转换为了 `https://mastodon.social/users/Gargron`,现在我们可以在需要时将此 URI 作为 `id`,通过 ActivityPub 进行交互。
|
||||
|
||||
{{< code title="示例活动" >}}
|
||||
```json
|
||||
{
|
||||
"id": "https://social.example/activities/1",
|
||||
"type": "Create",
|
||||
"actor": "https://social.example/actors/1",
|
||||
"object": {
|
||||
"id": "https://social.example/objects/1",
|
||||
"type": "Note",
|
||||
"content": "Hello, Gargron!"
|
||||
},
|
||||
"to": "https://mastodon.social/users/Gargron"
|
||||
}
|
||||
```
|
||||
{{< /code >}}
|
||||
|
||||
请注意,在上面的示例中,`social.example` 并未使用与 Mastodon 相同的 URI 结构。因此,我们无法仅根据用户名和域名猜测出行为体的 `id`。但是,如果 `social.example` 支持 WebFinger,那么我们可以通过请求 `https://social.example/.well-known/webfinger?resource=acct:username@social.example` 并解析响应中类型为 `application/ld+json; profile="https://www.w3.org/ns/activitystreams"` 或 `application/activity+json` 的链接来获取此 `id`。此链接还应具有 `rel="self"` 的链接关系。
|
||||
|
||||
## Mastodon 对 WebFinger 的要求
|
||||
|
||||
处理格式为 `username@domain` 或 `@username@domain` 的账户时,Mastodon 将执行以下操作:
|
||||
|
||||
- 使用该用户名和域名构造一个 `acct:` URI
|
||||
- 对该 `resource` 发起 WebFinger 请求
|
||||
|
||||
利用该 WebFinger 响应,Mastodon 将检查以下内容:
|
||||
|
||||
- `subject` 存在
|
||||
- `links` 数组包含一个链接,其 `rel` 为 `self` 且 `type` 为 `application/ld+json; profile="https://www.w3.org/ns/activitystreams"` 或 `application/activity+json`
|
||||
- 此链接的 `href` 解析为一个 ActivityPub Actor
|
||||
|
||||
利用该 ActivityPub 行为体表示(行为体表示可能在没有初始 WebFinger 请求的情况下被直接提供),Mastodon 将执行以下操作:
|
||||
|
||||
- 获取 `preferredUsername` 和行为体所在服务器的主机名
|
||||
- 使用该用户名和域名构造一个 `acct:` URI
|
||||
- 对该 `resource` 发起 WebFinger 请求
|
||||
|
||||
如果 `subject` 与 `resource` 匹配,则流程在此停止。否则,如果 `subject` 包含不同的规范账户 URI,则 Mastodon 将对该规范账户 URI 执行额外的 WebFinger 请求,以确保这个新的 `resource` 链接到同一个 ActivityPub Actor,并检查相同的条件。
|
||||
|
||||
换句话说,以下情况是有效的:
|
||||
|
||||
- 向 `example.com` 请求资源 `acct:alice@example.com`,返回一个指向域名 `example.com` 上 Actor 的链接,其 `preferredUsername` 为 `alice`,并且 `subject` 与请求的 `resource` `acct:alice@example.com` 匹配。
|
||||
- 向 `example.com` 请求资源 `acct:alice@example.com`,返回一个指向域名 `ap.example.com` 上 Actor 的链接,其 `preferredUsername` 为 `alice`。
|
||||
- ...然后,向 `ap.example.com` 请求资源 `acct:alice@ap.example.com`,返回的 `subject` 为 `acct:alice@example.com`,并链接到同一个行为体。
|
||||
|
||||
## 另请参阅
|
||||
|
||||
{{< caption-link url="https://github.com/mastodon/mastodon/blob/main/app/services/activitypub/fetch_remote_actor_service.rb" caption="app/services/activitypub/fetch_remote_actor_service.rb" >}}
|
||||
|
||||
{{< caption-link url="https://github.com/mastodon/mastodon/blob/main/app/services/resolve_account_service.rb" caption="app/services/resolve_account_service.rb" >}}
|
||||
|
||||
{{< caption-link url="https://github.com/mastodon/mastodon/blob/main/app/lib/webfinger.rb" caption="app/lib/webfinger.rb" >}}
|
||||
|
||||
{{< translation-status-zh-cn raw_title="WebFinger" raw_link="/spec/webfinger/" last_translation_time="2025-04-06" raw_commit="5e2b739ee193896bea937addc2843146ea0bc870">}}
|
Loading…
Add table
Add a link
Reference in a new issue