如何使用 Github Private Repo 作为图床并且不被科学
前序
Github 作为图床两大缺点: 链接会被科学,无法被更多人看到。并且 存储在公开的仓库有隐私问题。但是稳定,免费的优点实在让这俩个缺点瑕不掩瑜。而且有一些类似 PicGO 这样的开源项目集成了 Github 仓库作为图床,可以直接从剪切板上传图片到 repo。
Github 图床这么好用,这两个缺点一定要存在吗?我做了一些尝试,发现这两个问题是可以被解决的。废话不多说,直接上解决方案。
-
首先图片被科学是因为域名
raw.githubusercontent.com
脏了。我们只要买一个干净的域名,把任何raw.githubusercontent.com/<user>/<repo>/<branch>/path/to/image
用my.image.proxy.com/<user>/<repo>/<branch>/path/to/image
代替,并且域名把my.image.proxy.com
CNAME 到raw.githubusercontent.com
,就可以了。 -
公开的仓库有隐私问题,我们可以把图片放在 Github Private 仓库。为了 Private 仓库内的内容可以被访问,需要在请求头加上
Authorization
,就像这样:
curl -H 'Authorization: token INSERTACCESSTOKENHERE' \
-O \
-L https://raw.githubusercontent.com/repos/owner/repo/contents/path
但问题是用户用浏览器加载图片,不可能自己加上 Authorization
请求头,并且这个 Auth Token 不可能公开,不然仓库 Private 就没意义了。为了解决这个问题我们可以搞一层很薄的代理,把请求转发到 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 });
}
},
};
尾
配好之后,效果就像这样: