解決七牛雲bad token,Qt/C++ 實現上傳SDK

我以前寫了一個七牛雲的文件上傳的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

要是你有興趣,可以看看。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章