官方包中的getToSignByte的方法因为使用的是原生的http服务,在koa中不适用。
要计算body,直接使用koa-body等中间件返回的 ctx.request.body 直接 JSON.stringify即可。
直接上代码,需要的直接CV即可。
//ossCallbackV.js
const http = require("http");
const https = require("https");
const crypto = require("crypto");
async function readAllData(incoming) {
return new Promise((resolve, reject) => {
let rawData = "";
incoming.on("data", (chunk) => {
rawData += chunk;
});
incoming.on("end", () => {
resolve(rawData);
});
incoming.on("error", (e) => {
reject(e);
});
});
}
async function getPublicKey(ctx) {
const pubKeyUrl = Buffer.from(
ctx.headers["x-oss-pub-key-url"],
"base64"
).toString();
let httplib;
if (pubKeyUrl.startsWith("http://gosspublic.alicdn.com/")) {
httplib = http;
} else if (pubKeyUrl.startsWith("https://gosspublic.alicdn.com/")) {
httplib = https;
}
if (!httplib) {
throw new Error("Failed: x-oss-pub-key-url field is not valid.");
}
return new Promise((resolve, reject) => {
httplib.get(pubKeyUrl, async (res) => {
if (res.statusCode !== 200) {
reject(
new Error(
`Failed: Get OSS public key ${res.statusCode} ${res.statusMessage}`
)
);
} else {
resolve(await readAllData(res));
}
});
});
}
function getAuthorization(ctx) {
const authorization = ctx.headers["authorization"];
if (!authorization) {
throw new Error("Failed: authorization field is not valid.");
}
return Buffer.from(authorization, "base64");
}
async function getToSignByte(ctx) {
return new Promise(async (resolve, reject) => {
const body = ctx.request.body //koa直接使用 JSON.stringify 方法 转换成json字符串
const fullReqUrl = new URL(ctx.url, `http://${ctx.headers.host}`);
resolve(
decodeURIComponent(fullReqUrl.pathname) + fullReqUrl.search + "\n" + JSON.stringify(body))
})
}
function verifySignature(PublicKey, Authorization, ToSignByte) {
const verify = crypto.createVerify("RSA-MD5");
verify.update(ToSignByte);
return verify.verify(PublicKey, Authorization);
}
module.exports = { getPublicKey, getAuthorization, getToSignByte, verifySignature }
//index.js
const { getPublicKey, getAuthorization, getToSignByte, verifySignature } = require('./ossCallbackV')
const ToSignByte = await getToSignByte(ctx)
const PublicKey = await getPublicKey(ctx)
const Authorization = await getAuthorization(ctx)
const verify = await verifySignature(PublicKey, Authorization, ToSignByte)