我以前寫了一個七牛雲的文件上傳的Qt/C++ SDK,因爲官方沒有提供Qt SDK,提供的C++ SDK又依賴一些東西,與Qt也不是很好集成,於是就有了這點代碼。最近,因爲阿里雲OSS上傳文件後,沒有返回文件的URL,且文件的訪問還有有效期。我目前還沒有找到什麼辦法解決阿里雲OSS文件直傳後URL永久訪問的問題。所以,又回到了七牛雲的OSS。
七牛雲SDK,有C++的,我之前試過,但是同樣的依賴不少。百度了一下,
原文:https://blog.csdn.net/qq_32768743/article/details/87307822
自己挖的坑,還能咋辦,把代碼弄下來,然後跑了一下。和以前一樣,偶然出現bad token。非常奇怪,又拿着文檔看了看,發現
文檔:https://developer.qiniu.com/kodo/manual/1208/upload-token
所謂URL安全的Base64編碼,即
文檔:https://developer.qiniu.com/kodo/manual/1231/appendix#urlsafe-base64
而恰好,這裏我沒有實現。這就是bad token的根源了。快速解決掉這個問題,試了試,沒啥問題了。
代碼如下:
QString urlSafe(QString s) {
while (s.contains("+")) {
s = s.replace("+", "-");
}
while (s.contains("/")) {
s = s.replace("/", "_");
}
return s;
}
QString Auth::getUploadToken(QString bucket, QString key)
{
UploadPolicy policy;
policy.setBucket(bucket);
policy.setKey(key);
QString putPolicy = policy.toJSON();
QString encodePutPolicy = putPolicy.toLatin1().toBase64();
encodePutPolicy = urlSafe(encodePutPolicy);
QByteArray sign = hmac_sha1(encodePutPolicy.toLatin1(), m_secretKey.toLatin1());
// 這一步不能省,完成類型轉換
QString encodeSign = sign;
encodeSign = urlSafe(encodeSign);
QString uploadToken = QString("%1:%2:%3")
.arg(m_accessKey)
.arg(encodeSign)
.arg(encodePutPolicy);
qDebug() << encodeSign;
qDebug() << encodePutPolicy;
return uploadToken;
}
其中,hmac_sha1的實現抄的StackOverflow,網址忘了,後面想起來再補
/**
* Hashes the given string using the HMAC-SHA1 algorithm.
*
* \param key The string to be hashed
* \param secret The string that contains secret word
* \return The hashed string
*/
static QByteArray hmac_sha1(const QString &key, const QString &secret) {
// Length of the text to be hashed
int text_length;
// For secret word
QByteArray K;
// Length of secret word
int K_length;
K_length = secret.size();
text_length = key.size();
// Need to do for XOR operation. Transforms QString to
// unsigned char
// K = secret.toAscii();
K = secret.toLatin1();
// Inner padding
QByteArray ipad;
// Outer padding
QByteArray opad;
// If secret key > 64 bytes use this to obtain sha1 key
if (K_length > 64) {
QByteArray tempSecret;
tempSecret.append(secret);
K = QCryptographicHash::hash(tempSecret, QCryptographicHash::Sha1);
K_length = 20;
}
// Fills ipad and opad with zeros
ipad.fill(0, 64);
opad.fill(0, 64);
// Copies Secret to ipad and opad
ipad.replace(0, K_length, K);
opad.replace(0, K_length, K);
// XOR operation for inner and outer pad
for (int i = 0; i < 64; i++) {
ipad[i] = ipad[i] ^ 0x36;
opad[i] = opad[i] ^ 0x5c;
}
// Stores hashed content
QByteArray context;
// Appends XOR:ed ipad to context
context.append(ipad, 64);
// Appends key to context
context.append(key);
//Hashes inner pad
QByteArray Sha1 = QCryptographicHash::hash(context, QCryptographicHash::Sha1);
context.clear();
//Appends opad to context
context.append(opad, 64);
//Appends hashed inner pad to context
context.append(Sha1);
Sha1.clear();
// Hashes outerpad
Sha1 = QCryptographicHash::hash(context, QCryptographicHash::Sha1);
// String to return hashed stuff in Base64 format
QByteArray str(Sha1.toBase64());
return str;
}
整個代碼在
GitHub: https://github.com/PikachuHy/Oak-Pokemon-Research-Lab/tree/master/Qt/libQtQiniuSdk
要是你有興趣,可以看看。