如何使用 Github Private Repo 作为图床并且不被科学
Github 作为图床有两大缺点: 链接会被科学 并且 放在公开的仓库有隐私问题。但是稳定免费的优点实在让这俩个缺点瑕不掩瑜。而且有一些类似 PicGO 这样的开源项目集成了 Github 仓库作为图床,可以直接从剪切板上传图片到 repo。另外 markdown 所有的内容都可以被直接拷贝到其他位置,不用担心图片迁移的问题。
Github 图床这么好用,这两个缺点一定要存在吗?我做了一些尝试,发现这两个问题是可以被解决的。
-
解决链接被科学。购买一个干净的域名 CNAME 到
raw.githubusercontent.com
。然后把raw.githubusercontent.com/<user>/<repo>/<branch>/path/to/image
用my.image.proxy.com/<user>/<repo>/<branch>/path/to/image
代替(PicGo 这类工具可以配置自定义域名)。 -
公开的仓库有隐私问题,我们可以把图片放在 Github Private 仓库。为了 Private 仓库内的内容可以被访问,需要在请求头加上
Authorization
,就像这样:
curl -H 'Authorization: token INSERTACCESSTOKENHERE' \
-O \
-L https://raw.githubusercontent.com/repos/owner/repo/contents/path
但是用户浏览器加载图片不会带上 Authorization
,并且这个 Auth Token 不适合公开。为了解决这个问题可以搞一层很薄的代理,把请求转发到 Github Private 仓库,带上 Authorization
请求头。以 CloudFlare Worker 为例,推荐针对图床仓库 创建一个只读 token (opens in a new tab),配到 Worker 的 Secret 里:
export default {
async fetch(request, env) {
try {
const GITHUB_IMAGE_HOST = "raw.githubusercontent.com";
const GITHUB_TOKEN = env.repo_read_only_token;
if (!GITHUB_TOKEN) {
console.error("GitHub token not configured");
return new Response("Error: GitHub token not configured", {
status: 500,
});
}
const oldUrl = new URL(request.url);
if (oldUrl.pathname === "/") {
return new Response(`https://${oldUrl.hostname}/v1`, { status: 200 });
}
const newUrl = new URL(request.url);
newUrl.hostname = GITHUB_IMAGE_HOST;
const newHeaders = new Headers(request.headers);
newHeaders.set("Authorization", `token ${GITHUB_TOKEN}`);
newHeaders.set("Accept", "application/vnd.github.v3.raw");
const modifiedRequest = new Request(newUrl, {
method: request.method,
headers: newHeaders,
body: request.body,
});
const response = await fetch(modifiedRequest);
if (!response.ok) {
console.error(
`GitHub API error: ${response.status} ${response.statusText}`
);
return response;
}
return response;
} catch (e) {
console.error(e);
return new Response(e.stack, { status: 500 });
}
},
};
note: 虽然用代理屏蔽了直接对仓库内容的访问,但实际还是透风的,只要猜到图片名称,猜到资源名称,拼上新的域名仍然可以拿到图片,隐私的图片还是要慎重。
尾
配好之后,效果就像这样: