解决七牛云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

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

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