阿里api网关接口客户端demo, c语言实现源码,其他语言可参考,c语言base64,md5,cJSON,http,hmacsha源码
这篇文章介绍的是C语言阿里api网关接口demo,如果想看java或其他语言demo,可以看下博文:
https://blog.csdn.net/a704397849/article/details/89455262
https://blog.csdn.net/a704397849/article/details/89421342
本文只介绍了客户端实现,并没有去介绍对应的阿里网关上创建api的过程,需要的话看上述提供的博文链接.
声明
作者现在一直在做java后端开发,c语言已经有4年多没用了,基本忘得差不多了,如果下面介绍的c 客户端demo 写的不好还请见谅。写这篇文章的原因是C前端开发接入api网关进度慢,而项目又有点急,所以就自己捡起C自己动手了。
强调一下,本文目的只是为了介绍C 访问阿里api网关接口,所以下面代码可以做参考,如果要放进实际项目中还需要修改,比如动态分配的空间并没有去释放(java开发很少关心),http访问模块是在网上随意找的,虽然可以用但是有没有别的问题或缺少什么的就不清楚了。
开发环境:
- 虚拟机vmware 12
- ubuntu12 32位
- qt-sdk-linux-x86-opensource-2010.05.1.bin
如果需要安装上述一样的开发环境,so easy, 看下我另一篇博文:https://blog.csdn.net/a704397849/article/details/89926268
用到功能模块:
base64,md5,cJSON,http,hmacsha 等
我的工程结构如下:
运行结果:
[MSG_INFO][http_download(461)]:response head --->
[MSG_INFO][parse_http_header(215)]:http status code: 200
[MSG_INFO][parse_http_header(225)]:Server: Tengine
[MSG_INFO][parse_http_header(225)]:Date: Thu, 09 May 2019 07:43:16 GMT
[MSG_INFO][parse_http_header(225)]:Content-Type: application/json; charset=UTF-8
[MSG_INFO][parse_http_header(225)]:Content-Length: 40
[MSG_INFO][parse_http_header(232)]:Content-length: 40
[MSG_INFO][parse_http_header(225)]:Connection: keep-alive
[MSG_INFO][parse_http_header(225)]:Access-Control-Allow-Origin: *
[MSG_INFO][parse_http_header(225)]:Access-Control-Allow-Methods: GET,POST,PUT,DELETE,HEAD,OPTIONS,PATCH
[MSG_INFO][parse_http_header(225)]:Access-Control-Allow-Headers: X-Requested-With,X-Sequence,X-Ca-Key,X-Ca-Secret,X-Ca-Version,X-Ca-Timestamp,X-Ca-Nonce,X-Ca-API-Key,X-Ca-Stage,X-Ca-Client-DeviceId,X-Ca-Client-AppId,X-Ca-Signature,X-Ca-Signature-Headers,X-Ca-Signature-Method,X-Forwarded-For,X-Ca-Date,X-Ca-Request-Mode,Authorization,Content-Type,Accept,Accept-Ranges,Cache-Control,Range,Content-MD5
[MSG_INFO][parse_http_header(225)]:Access-Control-Max-Age: 172800
[MSG_INFO][parse_http_header(225)]:X-Ca-Request-Id: 88F768B4-776A-4D64-90D3-854D098AFCA6
[MSG_INFO][http_download(466)]:response head <---
[MSG_INFO][http_download(478)]:recv 40 bytes
[MSG_INFO][http_download(480)]:Average download speed: 0.04KB/s
body 内容写到了指定的文件 /home/zx/a.txt 中,内容如下:
注: 下面代码中有些涉及到公司内容的我屏蔽了,你们用自己的替换,见谅。
下面demo中nonce 用的随机生成的,并不是真正的nonce。
main.cpp
#include <stdio.h>
#include <time.h>
#include "cJSON.h"
#include "cHttp.h"
#include "string.h"
#include "base64.h"
#include "hmacsha.h"
#include "md5.h"
#include "sha1.h"
#include "sha256.h"
int get_md5(char *buff, char *md5_buf)
{
unsigned char decrypt[16] = {0};
unsigned char in_buf[4096] = {0};
MD5_CTX md5;
int i;
strcpy((char *)in_buf, buff);
MD5Init(&md5);
MD5Update(&md5,(unsigned char *)in_buf, strlen(( char *)in_buf));
MD5Final(&md5, decrypt);
printf("encrypt after:");
for (i = 0; i<16; i++)
{
printf("%02x", decrypt[i]);
}
printf("\n");
strcpy(md5_buf, ( char *)decrypt);
return 0;
}
int main(int argc, char *argv[])
{
char * appKey = "2xxxxxx8";
char * appSecret = "baexxxxxxxxxxxxxxxxxxxxxxxx08ff3";
char * apiGateWayHost = "xxxxxxxxxxxxxxxxxxxxxxx34f2d6025-cn-shenzhen.alicloudapi.com";
char * request_api = "/device/audio/query";
char url[1024] = {0};
sprintf(url,"http://%s%s",apiGateWayHost,request_api);
char * request_method = "POST";
char * stage = "TEST";
//time
time_t t;
t = time(NULL);
int ii = time(&t);
char * ctime = (char *)malloc(20);
memset(ctime,0,20);
sprintf(ctime,"%d000",ii);
//nonce , 注:这不是真正的nonce.
char s[] = {'a','b','c','d','e','0','1','2','3','4','5','6','7','8','9'};
int len = 15;
char * nonce = (char *)malloc(32);
memset(nonce,0,32);
srand((int)time(NULL));
for(int i = 0; i < 32;i++){
char c = s[rand()%len];
nonce[i] = c;
}
//head
char * method = request_method;
char * api = request_api;
char * http_version = "HTTP/1.1";
char * X_Ca_Timestamp = ctime;
char * Accept = "application/json";
char * X_Ca_Key = appKey;
char * X_Ca_Stage = stage;
char * Content_Type = "application/text; charset=UTF-8";
char * X_Ca_Nonce = nonce;
char * X_Ca_Signature_Headers = "X-Ca-Key,X-Ca-Nonce,X-Ca-Timestamp";
char * User_Agent = "Java/1.8.0_201";
char * Host = apiGateWayHost;
char * Connection = "keep-alive";
char * Content_MD5;
char * X_Ca_Signature;
//body md5
/*
cJSON *jo;
jo = cJSON_CreateObject();
if (jo == NULL){
printf("jo == null\n");
}
cJSON_AddItemToObject(jo, "name",cJSON_CreateString("zhangsan"));
char * jo_str = cJSON_Print(jo);
printf("jo_str=%s\n",jo_str);
char * data = jo_str;
*/
char * data = "123";
int contentLength = strlen(data);
char *md5_data = (char *)malloc(40);
memset(md5_data,0,40);
char *p_md5_data_Base64 = (char *)malloc(64);
memset(p_md5_data_Base64,0,64);
//get body content md5
get_md5(data,md5_data);
p_md5_data_Base64 = EncodeBase64A((const unsigned char*)md5_data, 16);
printf("p_md5_data_Base64: %s\n", p_md5_data_Base64);
Content_MD5 = p_md5_data_Base64;
//sign
//get signStr
char stringtoSign[2048] = {0};
sprintf(stringtoSign,"%s\n%s\n%s\n%s\n\nX-Ca-Key:%s\nX-Ca-Nonce:%s\nX-Ca-Timestamp:%s\n%s",method,Accept,Content_MD5,Content_Type,appKey,X_Ca_Nonce,X_Ca_Timestamp,api);
printf("stringtoSign=%s\n",stringtoSign);
//use signStr sign
char *p_Sign_Base64 = (char *)malloc(64);
memset(p_Sign_Base64,0,64);
char stringtoSign_out[1024] = {0};
int len_stringtoSign_out = 32;
char stringtoSign_byte2hex[1024];
hmac_sha256(appSecret, strlen(appSecret), stringtoSign, strlen(stringtoSign), stringtoSign_out, &len_stringtoSign_out);
printf("---HMACSHA256---\n DATA: ");
pr_sha((unsigned char*)stringtoSign_out, len_stringtoSign_out);
//_byte2hexstr(stringtoSign_out,stringtoSign_byte2hex,len_stringtoSign_out);
//printf("*********stringtoSign_byte2hex DATA: %s\n",stringtoSign_byte2hex);
p_Sign_Base64 = EncodeBase64A((const unsigned char*)stringtoSign_out, len_stringtoSign_out);
printf("BASE64: %s\n", p_Sign_Base64);
X_Ca_Signature = p_Sign_Base64;
//
// set head
char * send_data = (char *)malloc(2048);
memset(send_data,0,2048);
sprintf(send_data,"%s %s %s\r\nX-Ca-Timestamp:%s\r\nAccept:%s\r\nX-Ca-Key:%s\r\nX-Ca-Stage:%s\r\nX-Ca-Signature:%s\r\nContent-MD5:%s\r\nContent-Type:%s\r\nX-Ca-Nonce:%s\r\nX-Ca-Signature-Headers:%s\r\nUser-Agent:%s\r\nHost:%s\r\nConnection:%s\r\nContent-Length:%d\r\n\r\n%s",
method,api,http_version,X_Ca_Timestamp,Accept,X_Ca_Key,X_Ca_Stage,X_Ca_Signature,
Content_MD5,Content_Type,X_Ca_Nonce,X_Ca_Signature_Headers,User_Agent,Host,Connection,contentLength,data);
//
//post request
http_download(url, "/home/zx/a.txt",send_data);
// free
//...
return 0;
}
其他功能模块源码我就不一一展示了,内容有点多
项目源码:
链接:https://pan.baidu.com/s/1TbbithtUOD1syfWJJr-OYQ
提取码:539q
最后
上面c 阿里api网关客户端demo只是介绍了 阿里云APP 的认证方式 , 没有介绍 认证方式: OpenID Connect 的demo , 主要是因为我们C开发的设备端不需要登录获取token ,所以就没有介绍 OpenID Connect 认证方式的demo ,之前博文java 客户端demo 里面有介绍。
还有,上述只是介绍了post 非form请求,没有介绍get请求,这个需要你们自己去完善,这里已经把最麻烦的认证过程介绍了,其他的就容易了。