Uppy 伴侣应用
伴侣是一个开源服务器应用程序,它消除了身份验证的复杂性,并减轻了从远程源(如 Instagram、Google Drive 等)下载文件的成本。伴侣是一个服务器到服务器的协调器,它从源流式传输文件到目标,且文件从未在伴侣中存储。伴侣可以作为独立(自托管)应用程序运行,Transloadit 托管,或插入选定应用程序作为 Express 中间件。Uppy 客户端向伴侣请求远程文件,伴侣会下载并同时上传到您的 Tus 服务器 、AWS 桶 或任何支持 PUT、POST 或 Multipart 上传 的服务器。
这意味着用户从 Google Drive 用手机上传 5GB 的视频时,不会消耗他们的数据计划,而你也不必担心实现 OAuth。
我应该何时使用它?
如果你想要让用户从 Box、Dropbox、Facebook、Google Drive、Google 相册、Instagram、OneDrive、Unsplash、从 URL 导入 或 Zoom 下载文件 —— 你需要伴侣应用。
伴侣支持与 Uppy 相同的 上传器:Tus、AWS S3 和 常规 multipart 。但与手动设置插件不同,Uppy 会发送一个带有上传器的头部,伴侣将在服务器上使用相同的头部。这意味着如果你正在为本地上传使用 Tus ,你可以将远程上传发送到同一个 Tus 服务器(对于 AWS S3 桶也是一样)。
NOTE
伴侣只处理远程文件,本地文件仍然由客户端使用你的上传插件上传。
托管
使用 Transloadit 服务附带了一个托管版本的伴侣,因此你不必担心自己托管服务器。无论你是在免费还是付费的 Transloadit 计划 中,都可以使用伴侣。没有 Transloadit 计划,无法租用伴侣服务器。
TIP
选择 Transloadit 作为你的文件服务还提供了所有远程提供者的凭据。这意味着你不必浪费时间通过每个应用的批准过程。如果你愿意,仍然可以在 Transloadit 管理页面中添加自己的凭据。
INFO
通过伴侣下载和上传文件不计入你的 每月配额 ,这是文件到达 Transloadit 服务器的一种方式,就像 Uppy 一样。
安装和使用
伴侣通过 npm 安装。根据你如何运行伴侣,安装过程略有不同。伴侣可以作为中间件集成到你的 Express 应用中,也可以作为一个独立服务器运行。大多数人可能希望将其作为一个独立服务器运行,而中间件可用于进一步自定义伴侣或将其集成到你自己的 HTTP 服务器代码中。
NOTE
从 v2 开始,你需要运行 node.js >= v10.20.1
才能使用伴侣。更多信息,请参阅 [迁移到 2.0] 指南。
目前 Windows 不是支持的平台。它可能可以工作,我们很乐意接受这方面的改进,但我们无法提供支持。
独立模式
如果你想要将伴侣作为自己的 Node.js
进程运行,可以使用独立版本。它是一个配置好的 Express
服务器,具有会话、日志记录和最佳安全实践。通常,你首先想要全局安装它:
npm install -g @uppy/companion
独立伴侣始终提供 HTTP(非 HTTPS),并在生产环境中期望有一个反向代理进行 SSL 终止。有关更多信息,请参阅 COMPANION_PROTOCOL
( 服务器 )。
伴侣随附一个可执行文件(bin/companion
),即独立服务器。与中间件版本不同,选项是通过环境变量设置的。
查看 选项 以了解 JS 和环境变量格式中的可用选项。
你至少需要这三个来开始:
export COMPANION_SECRET="shh!Issa Secret!"
export COMPANION_DOMAIN="YOUR SERVER DOMAIN"
export COMPANION_DATADIR="PATH/TO/DOWNLOAD/DIRECTORY"
然后运行:
companion
你还可以传递 JSON 配置文件的路径,如下所示:
companion --config /path/to/companion.json
你可能还想在 PM2 这样的进程管理器中运行伴侣,以确保在崩溃时重新启动,以及允许扩展到多个实例。
Express 中间件模式
首先,使用你喜欢的包管理器将其安装到你的 Node.js 项目中:
npm install @uppy/companion
要将伴侣插入现有服务器,调用其 .app
方法,将一个 选项 对象作为参数传递。这返回一个服务器实例,你可以将其挂载在 Express 应用的路由上。
import express from "express";
import bodyParser from "body-parser";
import session from "express-session";
import companion from "@uppy/companion";
const app = express();
// 伴侣需要body-parser和express-session中间件。
// 如果你的应用程序中使用这些,请这样添加。
//
// 如果你的应用程序中使用其他东西,你可以在与伴侣相同的子路径下
// 添加这些中间件,例如 app.use('/companion', companionApp)
app.use(bodyParser.json());
app.use(session({ secret: "some secrety secret" }));
const companionOptions = {
providerOptions: {
drive: {
key: "GOOGLE_DRIVE_KEY",
secret: "GOOGLE_DRIVE_SECRET",
},
},
server: {
host: "localhost:3020",
protocol: "http",
// 默认安装通常不需要路径。
// 但是,如果你指定了`path`,你必须在下面的`app.use()`中指定相同路径,
// 例如:app.use('/companion', companionApp)
// path: '/companion',
},
filePath: "/path/to/folder/",
};
const { app: companionApp } = companion.app(companionOptions);
app.use(companionApp);
伴侣 Companion 使用 WebSocket 与客户端通信,向客户端发送进度、错误和成功信息。这是 Uppy 监听并更新其内部状态和 UI 的方式。
通过 companion.socket
函数添加伴侣 Companion 的 WebSocket 服务器:
const server = app.listen(PORT);
companion.socket(server);
如果 WebSocket 因某种原因失败,Uppy 和 Companion 将回退到 HTTP 轮询。
运行多个实例
我们建议在生产环境中至少运行两个实例,以防某个请求阻塞了 Node.js 事件循环(由于 bug 或流量激增),这样也不会阻塞或减慢所有其他请求(因为 Node.js 是单线程的)。
例如,Transloadit 的一位企业客户自托管了 Companion 来支持一项全球多所大学使用的教育服务,他们部署了 7 个 Companion 实例。而他们之前的解决方案运行在 35 个实例上。根据我们的经验,Companion 会在商品虚拟服务器(如 c5d.2xlarge
)的网络接口卡饱和之前耗尽其他资源。
你的使用情况可能有所不同,所以我们建议添加可观测性。你可以让 Prometheus 爬取 /metrics
端点,并用 Grafana 绘制图表。
使用唯一端点
一种选择是运行多个具有各自独特端点的实例。这些端点可以是不同的端口、子域名或 IP。在这种设置下,你可以:
- 实现自己的逻辑,通过设置
companionUrl
选项将每个上传定向到特定的 Companion 端点。 - 设置 Companion 选项
COMPANION_SELF_ENDPOINT
。这个选项会使 Companion 响应包含COMPANION_SELF_ENDPOINT
值的i-am
HTTP 头。当 Uppy 看到这个头时,它会将所有上传请求固定到该端点。
无论哪种情况,你通常还会配置一个单独的 Companion 实例(一个端点)来处理所有 OAuth 身份验证请求,这样你只需要指定一个 OAuth 回调 URL。参见 oauthDomain
和 validHosts
。
使用负载均衡器
另一种选择是在多个 Companion 实例前设置负载均衡器。然后 Uppy 只看到一个单一的端点,并将所有请求发送到关联的负载均衡器,后者再将请求分发给 Companion 实例。Companion 实例通过 Redis 协调消息和事件,以便任何实例都可以处理客户端的请求。注意,这种设置不需要粘性会话。以下是这种设置的要求:
- 实例需要连接到同一个 Redis 服务器。
- 在两台服务器上将
COMPANION_SECRET
设置为相同的值。 - 如果你使用
companionKeysParams
功能(Transloadit),则需要在每个实例上将COMPANION_PREAUTH_SECRET
设置为相同。 - 所有其他配置应相同,除非你在同一台机器上运行多个实例,那么每个实例的
COMPANION_PORT
应不同。
API
选项
提示
标题显示 JS 和环境变量选项( option
ENV_OPTION
)。当你将 Companion 集成到自己的服务器中时,将选项传递给 companion.app()
。如果你使用独立版本,可以通过环境变量配置 Companion。有些选项仅作为环境变量存在,有些仅作为 JS 选项存在。
默认配置
const options = { server: { protocol: "http", path: "", }, providerOptions: {}, s3: { endpoint: "https://{service}.{region}.amazonaws.com", conditions: [], useAccelerateEndpoint: false, getKey: (req, filename) => `${crypto.randomUUID()}-${filename}`, expires: 800, // 秒 }, allowLocalUrls: false, logClientVersion: true, periodicPingUrls: [], streamingUpload: false, clientSocketConnectTimeout: 60000, metrics: true, };
filePath
COMPANION_DATADIR
提供者文件将临时下载到的完整目录路径。
secret
COMPANION_SECRET
COMPANION_SECRET_FILE
Companion 用于生成授权令牌的密钥字符串。你应该生成一个长的随机字符串。例如:
const crypto = require("node:crypto");
const secret = crypto.randomBytes(64).toString("hex");
警告
在独立版本中省略 secret
将为你生成一个使用上述 crypto
字符串的密钥。但是,当你与 Express 集成时,必须自己提供。这是一个重要的安全措施。
注意
使用密钥文件意味着提供一个绝对路径到一个文件,文件中只有密钥,没有其他内容。
preAuthSecret
COMPANION_PREAUTH_SECRET
COMPANION_PREAUTH_SECRET_FILE
如果你使用 Transloadit 的 companionKeysParams
功能(使用你自己的自定义 OAuth 凭据的 Transloadit 托管的 Companion),将此变量设置为一个强大的随机生成的密钥。也参见 COMPANION_SECRET
(但不要使用相同的密钥!)
注意
使用密钥文件意味着提供一个绝对路径到一个文件,文件中只有密钥,没有其他内容。
oauthOrigin
COMPANION_OAUTH_ORIGIN
警告
强烈建议设置此选项。如果未设置( 或设置为 '*'
),则您的应用可能会被冒充。
此选项用于指定允许的 域(Origin),或是一个域数组(在 COMPANION_OAUTH_ORIGIN
中以逗号分隔的域)。任何来自未列出域的浏览器请求都将无法接收 OAuth2
令牌,并且 OAuth
请求将无法完成。将其设置为 '*'
以允许所有域(不推荐)。默认值:'*'
。
uploadUrls
COMPANION_UPLOAD_URLS
一个允许列表(字符串数组)或正则表达式。Companion 只接受这些 URL 的上传。这确保你的 Companion 实例只被允许向你的受信任服务器上传,防止 SSRF 攻击。
COMPANION_PORT
独立服务器启动时使用的端口,默认为 3020。这是一个仅适用于独立模式的选项。
COMPANION_COOKIE_DOMAIN
允许您自定义为 Express
会话创建的 cookies
的域。这是一个仅适用于独立模式的选项。
COMPANION_HIDE_WELCOME
将其设置为 true
可禁用在 /
路径显示的欢迎消息。这是一个仅适用于独立模式的选项。
redisUrl
COMPANION_REDIS_URL
运行中的 Redis 服务器的 URL。这可以用于使用多个实例水平扩展 Companion。参见 [如何扩展 Companion]。
COMPANION_REDIS_EXPRESS_SESSION_PREFIX
为 connect-redis 创建的 Redis 键设置自定义前缀。默认值为 sess:
。会话用于存储认证状态以及通过 Companion 从浏览器加载缩略图。如果在同一 Redis 服务器上运行了多个不同应用,你可能希望更改此设置,因为很难知道 sess:
来自何处,可能会与其他应用冲突。**注意:**将来我们计划将默认值更改为 companion:
,并可能删除此选项。这是一个仅适用于独立模式的选项。也请参阅 COMPANION_REDIS_PUBSUB_SCOPE
。
redisOptions
一个支持 redis 客户端选项 的对象。此选项可以替代 redisUrl
使用。
COMPANION_REDIS_PUBSUB_SCOPE
在 Redis 服务器上为 Companion 事件使用范围。设置此选项将使用提供的名称和冒号前缀所有事件。也请参阅 COMPANION_REDIS_EXPRESS_SESSION_PREFIX
。
server
基础服务器的配置选项。
键/环境变量 | 值 | 描述 |
---|---|---|
protocol COMPANION_PROTOCOL |
http 或 https |
用于构建引用 Companion 实例本身的 URL,用于头和饼干。Companion 本身始终作为 HTTP 服务器运行,因此本地应使用 http 。在生产环境中为您的域名启用 SSL/HTTPS(通过在 Companion 前面运行反向 https 代理,或使用托管服务的内置 HTTPS 功能)后,必须将其设置为 https 。 |
host COMPANION_DOMAIN |
字符串 |
您服务器的公共主机名(例如 example.com )。 |
oauthDomain COMPANION_OAUTH_DOMAIN |
字符串 |
如果您有多个具有不同(可能是动态)子域的 Companion 实例,可以设置一个单一固定子域和服务器(如 sub1.example.com ),以处理您的 OAuth 身份验证。然后,这将在完成时将您重定向回正确的实例,并提供所需的凭据。这样,您只需为 OAuth 提供商配置一个回调 URL。 |
path COMPANION_PATH |
字符串 |
Companion 应用程序所在的服务器路径。例如,如果 Companion 位于 example.com/companion ,则路径为 /companion 。 |
implicitPath COMPANION_IMPLICIT_PATH |
字符串 |
如果您的反向代理 URL 路径与 express 应用中的 Companion 路径不同,则需要设置此路径为 implicitPath 。例如,如果 Companion 的 URL 是 example.com/mypath/companion 。其中 /mypath 在您的 NGINX 服务器中定义,而 /companion 在您的 express 应用中设置。那么您需要将 implicitPath 选项设置为 /mypath ,并将 path 选项设置为 /companion 。 |
validHosts COMPANION_DOMAINS |
数组 |
如果设置了 oauthDomain ,则需要设置一个有效的主机列表,以便 OAuth 处理器可以验证请求身份验证的 Uppy 实例的主机。这基本上是一个运行 Companion 实例的有效域列表。列表也可以包含正则表达式模式。例如 ['sub2.example.com', 'sub3.example.com', '(\\w+).example.com'] |
sendSelfEndpoint
COMPANION_SELF_ENDPOINT
这实质上与 server.host + server.path
属性相同。设置此属性的主要原因是,当设置时,它会在每个响应请求的 i-am
头中添加该值。
providerOptions
一个用于启用提供商及其密钥和秘密的对象。例如:
{
"drive": {
"key": "***",
"secret": "***"
}
}
在使用独立版本时,您可以使用相应的环境变量或指向秘密文件(如 COMPANION_GOOGLE_SECRET_FILE
)。
秘密文件需要一个包含仅秘密、无其他内容的文件的绝对路径。
服务 | 键 | 环境变量 |
---|---|---|
Box | box |
COMPANION_BOX_KEY , COMPANION_BOX_SECRET , COMPANION_BOX_SECRET_FILE |
Dropbox | dropbox |
COMPANION_DROPBOX_KEY , COMPANION_DROPBOX_SECRET , COMPANION_DROPBOX_SECRET_FILE |
facebook |
COMPANION_FACEBOOK_KEY , COMPANION_FACEBOOK_SECRET , COMPANION_FACEBOOK_SECRET_FILE |
|
Google Drive | drive |
COMPANION_GOOGLE_KEY , COMPANION_GOOGLE_SECRET , COMPANION_GOOGLE_SECRET_FILE |
Google Photos | googlephotos |
COMPANION_GOOGLE_KEY , COMPANION_GOOGLE_SECRET , COMPANION_GOOGLE_SECRET_FILE |
instagram |
COMPANION_INSTAGRAM_KEY , COMPANION_INSTAGRAM_SECRET , COMPANION_INSTAGRAM_SECRET_FILE |
|
OneDrive | onedrive |
COMPANION_ONEDRIVE_KEY , COMPANION_ONEDRIVE_SECRET , COMPANION_ONEDRIVE_SECRET_FILE , COMPANION_ONEDRIVE_DOMAIN_VALIDATION (设置此变量为 true 可启用一个可用于验证您的应用的 OneDrive 路由) |
Zoom | zoom |
COMPANION_ZOOM_KEY , COMPANION_ZOOM_SECRET , COMPANION_ZOOM_SECRET_FILE , COMPANION_ZOOM_VERIFICATION_TOKEN |
s3
Companion 配备了 AWS S3 的签名端点。Uppy 客户端可以使用这些端点对直接上传到 S3 的请求进行签名,而不必在浏览器中暴露秘密 S3 密钥。Companion 还支持直接从 Dropbox 和 Instagram 等提供商上传文件到 S3。
s3.key
COMPANION_AWS_KEY
S3 访问密钥 ID。
s3.secret
COMPANION_AWS_SECRET
COMPANION_AWS_SECRET_FILE
S3 私有访问密钥。
使用秘密文件意味着传递一个包含仅秘密、无其他内容的文件的任意扩展名的绝对路径。
s3.endpoint
COMPANION_AWS_ENDPOINT
自定义 S3(兼容)服务的可选 URL。否则使用 AWS SDK 的默认值。
s3.bucket
COMPANION_AWS_BUCKET
要存储上传文件的桶的名称。
它可以是返回桶名称的 string
函数,并接受以下参数:
http.IncomingMessage
,HTTP 请求(对于远程上传将是null
)- 用户为文件提供的元数据(对于本地上传将是
undefined
)
s3.forcePathStyle
COMPANION_AWS_FORCE_PATH_STYLE
这增加了设置 S3 客户端的 forcePathStyle
选项的支持。在开发环境中与 Uppy/Companion
及 localstack
一同使用时,这是必要的。默认值为:false
。
s3.region
COMPANION_AWS_REGION
目标桶所在的数据中心区域。
COMPANION_AWS_PREFIX
所有上传键的可选前缀。这是一个仅适用于独立模式的选项。使用 express 中间件时,可以通过 getKey
选项实现相同功能。
s3.awsClientOptions
可以在 providerOptions.s3.awsClientOptions
对象中提供任何 AWS SDK 支持的 S3 选项,除了 以下选项:
accessKeyId
。相反,请使用providerOptions.s3.key
属性。这是为了使 Companion 不同功能的配置名称保持一致。secretAccessKey
。相反,请使用providerOptions.s3.secret
属性。这是为了使 Companion 不同功能的配置名称保持一致。
请注意,某些选项可能会因与 Companion 的假设冲突而导致错误行为。如果您发现特定选项不按预期工作,请在 Uppy 的存储库中 打开一个问题,以便我们可以在此记录。
s3.getKey(req, filename, metadata)
获取文件的键名。键是文件在存储桶中上传的路径。此选项应为一个接收三个参数的函数:
req
,http.IncomingMessage
,对于使用@uppy/aws-s3
插件的常规 S3 上传的 HTTP 请求。此参数对于使用@uppy/aws-s3
或@uppy/aws-s3-multipart
插件的分片上传不可用。对于远程上传,此参数为null
。filename
,上传文件的原始名称;metadata
,用户为文件提供的元数据。
该函数应返回一个字符串 key
。req
参数可用于将文件上传到存储桶中与用户特定的文件夹,例如:
app.use(authenticationMiddleware);
app.use(
uppy.app({
providerOptions: {
s3: {
getKey: (req, filename, metadata) => `${req.user.id}/${filename}`,
/* 认证选项 */
},
},
})
);
默认实现返回 filename
,因此所有文件将被上传到存储桶的根目录并保留其原始文件名。
app.use(
uppy.app({
providerOptions: {
s3: {
getKey: (req, filename, metadata) => filename,
},
},
})
);
在客户端签名时,此函数仅对分片上传调用。
COMPANION_AWS_USE_ACCELERATE_ENDPOINT
启用 S3 Transfer Acceleration。这是一个独立选项。
COMPANION_AWS_EXPIRES
设置预签名 URL 中的 X-Amz-Expires
查询参数(以秒为单位,默认:300)。这是一个独立选项。
COMPANION_AWS_ACL
为上传的对象设置 预定义的 ACL 。这是一个独立选项。
customProviders
此选项允许您添加自定义提供商,以及已经支持的提供商。更多信息,请参阅 添加自定义提供商 。
logClientVersion
一个布尔标志,告诉 Companion 是否在启动时记录其版本。
metrics
COMPANION_HIDE_METRICS
一个布尔标志,告诉 Companion 是否提供一个带有 Prometheus 指标的 /metrics
端点(默认情况下,指标是启用的)。
streamingUpload
COMPANION_STREAMING_UPLOAD
一个布尔标志,告诉 Companion 是否启用流式上传。如果启用,它将导致更快的上传,因为 Companion 将在下载的同时开始上传使用 stream.pipe
。如果 false
,文件将首先完全下载,然后上传。默认为 false
,但建议启用,尤其是当您预期上传大文件时。在未来版本中,默认值可能会更改为 true
。
maxFileSize
COMPANION_MAX_FILE_SIZE
如果设置了此值,Companion 将限制要处理的最大文件大小。如果没有设置,它将处理任何大小限制的文件(这是默认值)。
periodicPingUrls
COMPANION_PERIODIC_PING_URLS
如果设置了此值,Companion 将定期向指定的 URL 发送 POST 请求。这对于跟踪 Companion 实例作为心跳很有用。
periodicPingInterval
COMPANION_PERIODIC_PING_INTERVAL
周期性 ping 请求的间隔(以毫秒为单位)。
periodicPingStaticPayload
COMPANION_PERIODIC_PING_STATIC_JSON_PAYLOAD
一个可以 JSON.stringify
化的 JavaScript 对象,将作为周期性 ping 请求的 JSON 主体发送。
allowLocalUrls
COMPANION_ALLOW_LOCAL_URLS
一个布尔标志,告诉 Companion 是否允许请求本地 URL(非互联网 IP)。
警告
仅在开发中启用此功能。在生产中启用是一个安全风险。
corsOrigins
COMPANION_CLIENT_ORIGINS
允许的 CORS 源(默认为 true
)。作为 cors 的 origin
选项传递。
COMPANION_CLIENT_ORIGINS_REGEX
类似于 COMPANION_CLIENT_ORIGINS
,但允许使用单个正则表达式。如果使用此选项,将忽略 COMPANION_CLIENT_ORIGINS
。这是一个独立选项。
chunkSize
COMPANION_CHUNK_SIZE
控制 AWS S3 Multipart 和 Tus 上传的块大小。较小的值会导致更多的开销,但较大的值在网络连接不好的情况下会导致较慢的重试。传递给 tus-js-client 的 chunkSize
,以及 AWS S3 Multipart 的 partSize
。
enableUrlEndpoint
COMPANION_ENABLE_URL_ENDPOINT
将其设置为 false
以禁用 URL 功能 。默认:true
。
事件
companion.app()
返回的对象还有一个属性 companionEmitter
,它是一个 EventEmitter
,发出以下事件:
upload-start
- 当上传开始时,发出一个包含属性token
的对象,它是上传的唯一 ID。- token - 事件名称是
upload-start
中的令牌。事件具有以下属性:action
- 以下字符串之一:success
- 当上传成功时。error
- 当上传因错误而失败时。
payload
- 错误或成功负载。
使用 EventEmitter
处理完成的文件上传的示例代码:
const companionApp = companion.app(options);
const { companionEmitter: emitter } = companionApp;
emitter.on("upload-start", ({ token }) => {
console.log("上传开始", token);
function onUploadEvent({ action, payload }) {
if (action === "success") {
emitter.off(token, onUploadEvent); // 避免监听器泄露
console.log("上传完成", token, payload.url);
} else if (action === "error") {
emitter.off(token, onUploadEvent); // 避免监听器泄露
console.error("上传失败", payload);
}
}
emitter.on(token, onUploadEvent);
});
常见问题
有实时示例吗?
一个示例服务器正在运行于 https://companion.uppy.io。
认证和令牌机制是如何工作的?
本节描述了 Companion 和提供者之间的认证工作原理。虽然这种行为对所有提供者(Dropbox、Instagram、Google Drive 等)都相同,但在此部分我们将以 Dropbox 代替任何提供者。
以下是用户通过 Companion 使用 Dropbox 进行认证和上传时发生的步骤:
- 网站上的访问者点击 “连接到 Dropbox”。
- Uppy 向 Companion 发送请求,后者向 Dropbox 发送 OAuth 请求(需要在 Companion 中添加 Dropbox 的 OAuth 凭据)。
- Dropbox 会提示访问者登录,并询问是否允许网站访问您的文件。
- 如果访问者同意,Companion 将从 Dropbox 收到一个令牌,我们可以用它临时下载文件。
- Companion 使用密钥加密令牌并将其发送给 Uppy(客户端)。
- 每当访问者在 Uppy 中点击文件夹时,都会向 Companion 请求新文件列表,并随请求发送加密的令牌。
- Companion 解密令牌,请求 Dropbox 中的文件列表,并将其发送给 Uppy。
- 当选择文件进行上传时,Companion 会按照此流程再次接收令牌,再次解密,然后从 Dropbox 下载文件。
- 伴奏者收到字节后,将字节上传到最终目的地(根据配置:Apache、Tus 服务器、S3 存储桶等)。
- Companion 向 Uppy 报告进度,就像本地上传一样。
- 完成!
如何使用提供者重定向 URI?
在相应的开发平台上(例如 Google 开发者控制台)生成提供者的 API 密钥时,您需要提供一个 redirect URI
用于 OAuth 授权过程。一般来说,每个提供者的重定向 URI 格式如下:
http(s)://$YOUR_COMPANION_HOST_NAME/$PROVIDER_NAME/redirect
例如,如果您的 Companion 服务器托管在 https://my.companion.server.com
上,则 OneDrive 提供者的重定向 URI 将是:
https://my.companion.server.com/onedrive/redirect
请参阅 [支持的提供者] 查看所有提供者及其对应的名称列表。
如何在 Kubernetes 中使用 Companion?
我们有一个详细的指南,关于如何在 Kubernetes 中运行 Companion:Kubernetes 。
如何添加自定义提供者?
目前,Companion 支持 [此处列出的提供者] ,但您也可以选择添加自己的自定义提供者。您可以通过在调用 Uppy app
方法时传递 customProviders
选项来实现。自定义提供者应支持 OAuth 1 或 2 用于身份验证/授权。
import providerModule from "./path/to/provider/module";
const options = {
customProviders: {
myprovidername: {
config: {
authorize_url: "https://mywebsite.com/authorize",
access_url: "https://mywebsite.com/token",
oauth: 2,
key: "***",
secret: "***",
scope: ["read", "write"],
},
module: providerModule,
},
},
};
uppy.app(options);
customProviders
选项应是一个包含每个自定义提供者的对象。每个自定义提供者反过来是一个包含两个键的对象:config
和 module
。config
选项将包含 OAuth API 设置,而 module
将指向提供者模块。
为了与 Companion 兼容,module 必须是一个具有以下方法的类。请注意,这些方法必须是 async
的,返回 Promise
或以 Error
拒绝:
async list ({ token, directory, query })
- 返回一个包含用户文件列表的对象(例如特定目录中所有文件的列表)。请参阅 返回的列表数据结构示例。token
- 与请求一起发送的授权令牌(从 OAuth 过程中获取)directory
- 要从中检索数据的目录的 ID/名称。如果这不适用于您的提供者,可以忽略。query
- 服务器接收到的 expressjs 查询参数对象(以防您需要其中的数据)。
async download ({ token, id, query })
- 从提供者下载特定文件。返回一个具有单一属性{ stream }
的对象 - 一个stream.Readable
,将从该流读取并上传到目的地。为了避免内存泄漏,请确保在拒绝此方法时释放您的流。token
- 与请求一起发送的授权令牌(从 OAuth 过程中获取)。id
- 正在下载的文件的 ID。query
- 服务器接收到的 expressjs 查询参数对象(以防您需要其中的数据)。
async size ({ token, id, query })
- 作为Number
返回需要下载的文件的字节大小。如果对象的大小未知,可以返回null
。token
- 与请求一起发送的授权令牌(从 OAuth 过程中获取)。id
- 正在下载的文件的 ID。query
- 服务器接收到的 expressjs 查询参数对象(以防您需要其中的数据)。
该类还必须具有:
- 一个唯一的
static authProvider
字符串属性 - 一个表示要使用的grant
(OAuth2 提供者)的小写值(例如,对于 Google,为google
)。如果您的提供者不使用 OAuth2,您可以省略此属性。 - 一个静态属性
static version = 2
,这是 Companion 提供者 API 的当前版本。
参考 示例代码,自定义提供者
列表数据
{
// 用户名或访问的提供者账户的电子邮件
"username": "johndoe",
// 目录中的文件和文件夹列表。如果主要用作包含子项的集合,则视为文件夹
"items": [
{
// 是否为文件夹的布尔值
"isFolder": false,
// 图标图像URL
"icon": "https://random-api.url.com/fileicon.jpg",
// 项目名称
"name": "myfile.jpg",
// 项目的MIME类型。仅在项目不是文件夹时相关
"mimeType": "image/jpg",
// 项目的ID(字符串)
"id": "uniqueitemid",
// 缩略图图像URL。仅在项目不是文件夹时相关
"thumbnail": "https://random-api.url.com/filethumbnail.jpg",
// 对于文件夹,这通常是将在list(...)方法中传递的值。对于文件,这是将在download(...)方法中传递的id。
"requestPath": "file-or-folder-requestpath",
// 项目最后修改的日期时间字符串(ISO 8601 格式)
"modifiedDate": "2020-06-29T19:59:58Z",
// 项目大小(以字节为单位)。仅在项目不是文件夹时相关
"size": 278940,
"custom": {
// 可能包含更多自定义字段的对象,您可能需要将其发送到客户端。仅当有需求时添加此对象。
"customData1": "the value",
"customData2": "the value"
}
// 更多项目在这里
}
],
// 如果“items”列表分页,这是获取下一页所需的请求路径
"nextPagePath": "directory-name?cursor=cursor-to-next-page"
}
如何本地运行 Companion?
要为本地开发设置 Companion,请克隆 Uppy 存储库并安装,如下所示:
git clone https://github.com/transloadit/uppy cd uppy yarn install
通过复制
.env.example.sh
文件到.env.sh
并编辑为正确的值来配置环境变量。cp .env.example .env $EDITOR .env
要启动服务器,运行:
yarn run start:companion
这将在 http://localhost:3020
上运行 Companion 实例。它使用 nodemon ,因此当文件更改时会自动重启。