多吉云文档
https://docs.dogecloud.com/oss/sdk-introduction
基本代码
公共代码-鉴权
在文档里有这个介绍:
dogeCLoudApi的代码如下:
var axios = require('axios');
var crypto = require('crypto');
var querystring = require('querystring');
/**
* 调用多吉云API
*
* @param {string} apiPath 调用的 API 接口地址,包含 URL 请求参数 QueryString,例如:/console/vfetch/add.json?url=xxx&a=1&b=2
* @param {object} data POST 的数据,对象,例如 {a: 1, b: 2},传递此参数表示不是 GET 请求而是 POST 请求
* @param {boolean} jsonMode 数据 data 是否以 JSON 格式请求,默认为 false 则使用表单形式(a=1&b=2)
* @param {function} callback 回调函数,兼容老版本调用代码,有两个参数,第一个参数表示错误,第二个参数是返回的数据
*
* @returns {Promise} 返回一个 Promise,在传递 callback 的情况下,可用 .then() 和 .catch() 处理返回的数据
*/
function dogecloudApi(apiPath, data = {}, jsonMode = false, callback = null) {
// 这里替换为你的多吉云永久 AccessKey 和 SecretKey,可在用户中心 - 密钥管理中查看
// 请勿在客户端暴露 AccessKey 和 SecretKey,那样恶意用户将获得账号完全控制权
const accessKey = '你的AccessKey';
const secretKey = '你的SecretKey';
const body = jsonMode ? JSON.stringify(data) : querystring.encode(data);
const sign = crypto.createHmac('sha1', secretKey).update(Buffer.from(apiPath + "\n" + body, 'utf8')).digest('hex');
const authorization = 'TOKEN ' + accessKey + ':' + sign;
return new Promise(function(resolve, reject) {
try {
axios.request({
url: 'https://api.dogecloud.com' + apiPath,
method: 'POST',
data: body,
responseType: 'json',
headers: {
'Content-Type': jsonMode ? 'application/json' : 'application/x-www-form-urlencoded',
'Authorization': authorization
}
})
.then(function (response) {
if (response.data.code !== 200) { // API 返回错误
callback ? callback({Error: 'API Error: ' + response.data.msg}, null) : reject({errno: response.data.code, msg: 'API Error: ' + response.data.msg});
return
}
callback ? callback(null, response.data.data) : resolve(response.data.data);
})
.catch(function (err) {
callback ? callback(err, null) : reject(err);
});
} catch (error) {
callback ? callback(error, null) : reject(err);
}
});
}
引入 AWS JS SDK
npm install aws-sdk --save
// 节省体积,只引入 S3 服务(推荐)
const S3 = require('aws-sdk/clients/s3');
// 或者:引入整个 AWS 包(不推荐)
const AWS = require('aws-sdk'); // 请注意如果这样引入,下方代码中所有 “S3” 类名,需要改为 “AWS.S3”
初始化 AWS S3 SDK
先获取密钥:
// 该 API 参考文档: https://docs.dogecloud.com/oss/api-tmp-token
dogecloudApi('/auth/tmp_token.json', {
channel: 'OSS_FULL',
scopes: ['*']
}, true, function(err, data) {
if (err) { console.log(err.Error); return; }
const credentials = data.Credentials;
console.log(credentials);
// 这里推荐使用 Redis 之类的缓存将获取到的临时密钥缓存下来,两小时内有效
})
然后使用密钥,初始化S3实例:
const s3 = new S3({ // 用服务端返回的信息初始化一个 S3 实例
region: 'automatic',
endpoint: data.Buckets[0].s3Endpoint, // 存储空间的 s3Endpoint 值,控制台存储空间 SDK 参数选项卡中也可以找到
credentials: credentials,
params: {
Bucket: data.Buckets[0].s3Bucket // 存储空间的 s3Bucket 值,控制台存储空间 SDK 参数选项卡中也可以找到,
// 这里先绑定好 s3Bucket,之后如果操作的是同一个存储空间,就不用再传递 Bucket 了
}
});
上传代码
// 节省体积,只引入 S3 服务(推荐)
import S3 from "aws-sdk/clients/s3";
import {
NODE_ENV,
OSS_ACCESS_KEY_ID,
OSS_ACCESS_KEY_SECRET,
OSS_BUCKET,
OSS_REGION,
} from "@/config";
import { myLog } from "./utils";
var axios = require("axios");
var crypto = require("crypto");
var querystring = require("querystring");
// 将顶层 await 移到一个异步函数中
async function initializeS3() {
try {
// TODO 读取redis是否存在临时密钥
// 获取临时密钥
const data = await dogecloudApi(
"/auth/tmp_token.json",
{
channel: "OSS_FULL",
scopes: ["*"],
},
true,
);
myLog(data);
// 初始化 S3 客户端
const s3Client = new S3({
region: "automatic",
endpoint: process.env.R2_ENDPOINT,
credentials: data?.Credentials,
params: {
Bucket: process.env.R2_BUCKET,
},
});
s3Client;
return s3Client;
} catch (error) {
console.error(error);
}
}
// 这个方法用于获取 S3 客户端
export default async function getDogeOSS() {
try {
return await initializeS3();
} catch (error) {
console.error(error);
return null;
}
}
/**
/**
* 调用多吉云API
*
* @param {string} apiPath 调用的 API 接口地址,包含 URL 请求参数 QueryString,例如:/console/vfetch/add.json?url=xxx&a=1&b=2
* @param {object} data POST 的数据,对象,例如 {a: 1, b: 2},传递此参数表示不是 GET 请求而是 POST 请求
* @param {boolean} jsonMode 数据 data 是否以 JSON 格式请求,默认为 false 则使用表单形式(a=1&b=2)
* @param {function} callback 废弃 回调函数,兼容老版本调用代码,有两个参数,第一个参数表示错误,第二个参数是返回的数据
* @returns {Promise} 返回一个 Promise,在传递 callback 的情况下,可用 .then() 和 .catch() 处理返回的数据
*/
function dogecloudApi(
apiPath: string,
data = {},
jsonMode = false,
callback = null,
) {
// 这里替换为你的多吉云永久 AccessKey 和 SecretKey,可在用户中心 - 密钥管理中查看
// 请勿在客户端暴露 AccessKey 和 SecretKey,那样恶意用户将获得账号完全控制权
const accessKey = process.env.R2_ACCESSKEYID;
const secretKey = process.env.R2_SECRET_ACCESSKEY;
const body = jsonMode ? JSON.stringify(data) : querystring.encode(data);
const sign = crypto
.createHmac("sha1", secretKey)
.update(Buffer.from(apiPath + "\n" + body, "utf8"))
.digest("hex");
const authorization = "TOKEN " + accessKey + ":" + sign;
return new Promise(function (resolve, reject) {
try {
axios
.request({
url: "https://api.dogecloud.com" + apiPath,
method: "POST",
data: body,
responseType: "json",
headers: {
"Content-Type": jsonMode
? "application/json"
: "application/x-www-form-urlencoded",
Authorization: authorization,
},
})
.then(function (response: any) {
if (response.data.code !== 200) {
// API 返回错误
callback
? callback({ Error: "API Error: " + response.data.msg }, null)
: reject({
errno: response.data.code,
msg: "API Error: " + response.data.msg,
});
return;
}
callback
? callback(null, response.data.data)
: resolve(response.data.data);
})
.catch(function (err: any) {
callback ? callback(err, null) : reject(err);
});
} catch (error) {
callback ? callback(error, null) : reject(error);
}
});
}
/**
* 获取文件的 Content-Type
*/
export function getContentType(fileName: string) {
const ext = fileName.split(".").pop()?.toLowerCase();
const mimeTypes = {
jpg: "image/jpeg",
jpeg: "image/jpeg",
png: "image/png",
gif: "image/gif",
webp: "image/webp",
pdf: "application/pdf",
// 可以根据需要添加更多类型
};
return mimeTypes[ext || ""] || "application/octet-stream";
}
踩坑
putObject需要回调函数
await dogeOSS.putObject(params, function (err, data) {
if (err) console.error("uploadImg", err, err.stack);
else {
console.log("uploadImg", data);
}
});
如果不传递回调函数,会导致根本没能成功上传
如何结合Url进行鉴权?
https://docs.dogecloud.com/cdn/manual-auth-key
cant find server acion
需要明示是哪一个接口