使⽤Qt调⽤阿⾥云API接⼝
之前没接触过http的东西,由于⼯作原因,需要调⽤阿⾥云提供的云端API服务,与通常的Http不同的是多出来⼀个签名认证的过程,阿⾥那边没有C和C++的例⼦,只能⾃⼰捣⿎了⼀段时间,使⽤Qt完成了这个功能,记录⼀下防⽌以后忘记。
1.Http原理
HTTP 消息结构
先来看⼀下 HTTP 的消息结构
先看客户端发送信息
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:"<<baseString<<__LINE__;
qDebug()<<"baseStringToHex:"<&Hex(':')<<__LINE__;
QByteArray sign = QMessageAuthenticationCode::hash(baseString,key,QCryptographicHash::Sha256).toBase64();    QString signature = sign;
header.insert("X-Ca-Signature",Latin1());
qDebug() << "sign:" << sign;
}
获取参与签名的URL的函数
QString AliApi::UrlToSign()
{
QString url = requset_api;
pty())
{
return url;
}
else
{
url.append('?');
QMap<QString,QString>::iterator it;
for(it = queryparams.begin(); it != d();++it)
{
if(it.value().length() == 0)
{
url.append(it.key());
if( it != d() - 1)
{
url.append('&');
}
}
else
{
url.append(it.key() + '=' + it.value().toUtf8());
if( it != d() - 1)
{
url.append('&');
}
}
}
return url;
}
}
获取签名字符串的函数
QString AliApi::StringToSign()
{
QString signheader;    //⽤于签名计算的header
QString signurl;        //⽤于签名的url
//⽣成body的MD5值并返回给header.value("");ps:现在都使⽤GET请求,⽆body,所以这段代码没有测试过
//qDebug()<<"bodystream lenth:"<<bodystream.length();
if(!(bodystream.length() == 0))
百度api接口
{
header["Content-MD5"] = GetMD5(bodystream);
}
//获取时间
QLocale lo = QLocale::English;                                      //设置QLocale为英⽂
header["Date"] = lo.toString(QDateTime::currentDateTime(),"ddd dd MMM yyyy hh:mm:ss")+QString(" GMT+0800 (CST)");
qDebug() << "Date:"<<header.value("Date");
//⽣成随机数
QUuid id = QUuid::createUuid();
header["X-Ca-Nonce"] = id.toString().remove("{").remove("}"); //获取UUid并去除左右括号
qDebug()<< "X-Ca-Nonce:"<<header.value("X-Ca-Nonce");
/*
*遍历header中的key值,将X-Ca但不包括X-Ca-Signature、X-Ca-Signature-Headers的键加⼊X-Ca-Signature-Headers的value中,    * 将键对值加⼊signatureheader中
* 将键对值加⼊signatureheader中
*/
QMap<QString,QString>::iterator it;
for(it = header.begin();it != d(); ++it)
{
if(!(it.key().startsWith("X-Ca-",Qt::CaseInsensitive)))
{
continue;
}
if(it.key()pare("X-Ca-Signature",Qt::CaseInsensitive)==0 || it.key()pare("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:"<<header.value("X-Ca-Signature-Headers");
//将signatureheader键对值拼接成字符串
for(it = signatureheader.begin();it != d(); ++it)
{
signheader.append(it.key().toLower() + ':' + it.value());
if(it != d() - 1 )
{
signheader.append("\n");
}
}
qDebug()<<"signheader:"<<signheader;
signurl = UrlToSign();
qDebug()<<"signurl:"<<signurl;
QString ret = header.value("HTTPMethod") + "\n" + header.value("Accept") + "\n" + header.value("Content-MD5") + "\n"
+ header.value("Content-Type") + "\n" + header.value("Date") + "\n" + signheader +"\n" + signurl ;
QString temp = ret;
qDebug()<<"temp:"<&place(QRegExp("\n"), "#").toUtf8().toHex(':');
return ret;
}
核⼼代码都在这⾥了。仅供参考学习。
在上⾯的那张截图中可以看到服务器端返回正确回馈
回馈的信息头如图所⽰

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。