使用Qt调用阿里云API接口

之前没接触过http的东西,由于工作原因,需要调用阿里云提供的云端API服务,与通常的Http不同的是多出来一个签名认证的过程,阿里那边没有C和C++的例子,只能自己捣鼓了一段时间,使用Qt完成了这个功能,记录一下防止以后忘记。

 

1.Http原理

HTTP 消息结构

先来看一下 HTTP 的消息结构

使用Qt调用阿里云API接口_第1张图片

先看客户端发送信息

GET /music/v1/search?keywords=%E6%B5%B7%E9%98%94%E5%A4%A9%E7%A9%BA HTTP/1.1\r\n

GET:请求方法

/music/v1/search?keywords=%E6%B5%B7%E9%98%94%E5%A4%A9%E7%A9%BA:URL中的PATH路径

Content-Type:客户端发送内容的格式

Accept:客户端希望接收的内容格式

HOST:域名

Date:日期

Content-MD5:body区非From数据的MD5值

X-Ca-Key:秘钥,相当于签名认证的用户名

X-Ca-Nonce:UUID值,是一个随机数

X-Ca-Signature:签名字符串通过加密算法得到的哈希值,与服务器端生成的哈希值进行比较

一般要处理的数据就这些,其他都能自动生成。重点是签名的过程,阿里官方文档链接这里。

注意:特别要注意参与签名的字符串编码格式(尤其是中文)和大小写敏感问题,在这个地方卡了2天时间。。。

话不多说,直接上代码。

body获取MD5值的函数

QByteArray AliApi::GetMD5(QByteArray bytes_)
{
    QCryptographicHash ch(QCryptographicHash::Md5);
    QByteArray ret;
    ch.addData(bytes_);
    ret = ch.result().toBase64();
    return ret;
}

 

获取签名字符串通过算法获取哈希值的函数

void AliApi::HMACSha256(QByteArray key, QByteArray baseString)
{
    qDebug()<<"baseString:"<

获取参与签名的URL的函数

QString AliApi::UrlToSign()
{
    QString url = requset_api;
    if(queryparams.empty())
    {
        return url;
    }
    else
    {
        url.append('?');

        QMap::iterator it; 
        for(it = queryparams.begin(); it != queryparams.end();++it)
        {
            if(it.value().length() == 0)
            {
                url.append(it.key());
                if( it != queryparams.end() - 1)
                {
                    url.append('&');
                }
            }
            else
            {
                url.append(it.key() + '=' + it.value().toUtf8());
                if( it != queryparams.end() - 1)
                {
                    url.append('&');
                }
            }
        }

        return url;
    }
}

获取签名字符串的函数

QString AliApi::StringToSign()
{
    QString signheader;     //用于签名计算的header
    QString signurl;        //用于签名的url

    //生成body的MD5值并返回给header.value("");ps:现在都使用GET请求,无body,所以这段代码没有测试过
    //qDebug()<<"bodystream lenth:"<::iterator it;
    for(it = header.begin();it != header.end(); ++it)
    {
        if(!(it.key().startsWith("X-Ca-",Qt::CaseInsensitive)))
        {
            continue;
        }

        if(it.key().compare("X-Ca-Signature",Qt::CaseInsensitive)==0 || it.key().compare("X-Ca-Signature-Headers",Qt::CaseInsensitive)==0)
        {
            continue;
        }
        header["X-Ca-Signature-Headers"].append(it.key()+',');

        signatureheader.insert(it.key(),it.value());
    }
    //去掉最后一个','
    if(header["X-Ca-Signature-Headers"].right(1) == ',')
    {
        header["X-Ca-Signature-Headers"].chop(1);
    }
    qDebug()<<"X-Ca-Signature-Headers:"<

核心代码都在这里了。仅供参考学习。

 

在上面的那张截图中可以看到服务器端返回正确回馈

使用Qt调用阿里云API接口_第2张图片

回馈的信息头如图所示

 

 

 

 

 

 

你可能感兴趣的:(网络编程)