前言
官方文档只有java版的jdk和几个简陋的说明,并没有完整的demo。公司有一个.net项目需要对接csb服务,本人查看java的jdk源码和官方说明的实现了.net调用csb的完整代码。
csb接口说明
这里已http调用为例
调用csb接口参数分两部分
1 附加在header里参数
_api_timestamp:1592225468715 //时间戳
_api_name:http2http11 //服务名称
_api_signature:签名值
_api_version:1.0.0 //版本
_api_access_key: ak123 //ccess_key
Content-Type:application/x-www-form-urlencoded;charset=UTF-8
复制代码
2 附加在报文body里或url里的参数(这里请自行参考webapi)
这里参数是业务请求参数是xml,json或x-www-form-urlencoded形式出现的
其中x-www-form-urlencoded参与签名计算xml,json不参与。
实现步骤如下
按请求方式分为get方式和post方式分开介绍,因为两种方式参数形式不一样。
get方式实现
第一步:声明一个配置类放ACCESS_KEY,SECRET_KEY,csb地址等
public class Constants
{
public const String ACCESS_KEY = "3212432dewewqadwr4532das";
public const String SECRET_KEY = "232f321lYZ7wjrzdsaYeods12D4rdak=";
public const String APP_KEY = "123456789";
public const String CSB_ADDR = "http://ip/CSB";
}
复制代码
第二步:签名方法实现(参考官方实现,其中有个坑点)
public static string sign(string apiName, string apiVersion, long timeStamp, string accessKey, string secretKey, Dictionary<string, object[]> formParamDict, object body)
{
Dictionary<string, object[]> newDict = new Dictionary<string, object[]>();
if (formParamDict != null)
{
foreach (KeyValuePair<string, object[]> pair in formParamDict)
{
newDict.Add(pair.Key, pair.Value.Select(v => { return HttpUtility.UrlEncode(v.ToString()); }
).ToArray());
}
}
//设置csb要求的头参数,【将这四个参数+业务请求参数排序后签名】
newDict.Add("_api_name", new String[] { apiName });
newDict.Add("_api_version", new String[] { apiVersion });
newDict.Add("_api_access_key", new String[] { accessKey });
newDict.Add("_api_timestamp", new object[] { timeStamp });
****
//对所有参数进行排序
//var sortedDict = from pair
// in newDict
// orderby pair.Key
// select pair;
//【上面的是错误的请按照下面的方法实现】
var sortedDict = getSortByASCII(newDict);
StringBuilder builder = new StringBuilder();
foreach (KeyValuePair<string, object[]> pair in sortedDict)
{
foreach (object obj in pair.Value)
{
builder.Append(string.Format("{0}={1}&", pair.Key, obj));
}
}
string str = builder.ToString();
if (str.EndsWith("&"))
{
str = str.Substring(0, str.Length - 1); //去掉最后一个多余的 & 符号
}
System.Security.Cryptography.HMACSHA1 hmacsha = new System.Security.Cryptography.HMACSHA1
{
Key = Encoding.UTF8.GetBytes(secretKey)
};
byte[] bytes = Encoding.UTF8.GetBytes(str);
return Convert.ToBase64String(hmacsha.ComputeHash(bytes));
}
///排序方法,这里注意
public static Dictionary<string, object[]> getSortByASCII(Dictionary<string, object[]> dict) {
//这种排序是错误的
// sortList.Sort((x, y) => {
// var r = string.Compare(x.Key, y.Key);
//return r;
// });
//经过测试以下三种是正确的,会按照ASCII码排序
var sortList = dict.ToList();
sortList.Sort((x, y) => {
return string.CompareOrdinal(x.Key, y.Key);
});
sortList.Sort((x, y) => {
var r = string.Compare(x.Key, y.Key, StringComparison.Ordinal);
return r;
});
Dictionary<string, object[]> sortDict = new Dictionary<string, object[]>();
var keys = dict.Keys.ToArray();
Array.Sort(keys, string.CompareOrdinal); //an
foreach (var key in keys) {
sortDict.Add(key, dict[key]);
}
return sortDict;
}
复制代码
第三步组合请求报文,发送http的get请求
请求url和url参数(csb服务地址+业务参数):
Constants.CSB_ADDR?业务参数1=value1&业务参数2=value2
请求报文headers参数
_api_timestamp:1592225468715 //时间戳
_api_name:http2http11 //服务名称
_api_signature:签名值
_api_version:1.0.0 //版本
_api_access_key: ak123 //ccess_key
Content-Type:application/x-www-form-urlencoded;charset=UTF-8
//get时额外header(参考java_sdk源码还有以下几个额外的header参数)
headerDic.Add("Accept-Encoding", "gzip");
headerDic.Add("_inner_ecsb_request_id", "c0a8694816245153618221001d41d0"); //请求id随机一个\
headerDic.Add("_inner_ecsb_rpc_id", "0");
headerDic.Add("_inner_ecsb_trace_id", "c0a8694816245141995961002d3ef4"); // _inner_ecsb_trace_id随机一个\
复制代码
【注意时间戳实现】使用UnixTime
public static long ToUnixTimeMilliseconds(this DateTime nowTime) {
DateTime startTime = TimeZone.CurrentTimeZone.ToLocalTime(new System.DateTime(1970, 1, 1, 0, 0, 0, 0));
long unixTime = (long)Math.Round((nowTime - startTime).TotalMilliseconds, MidpointRounding.AwayFromZero);
return unixTime;
}
复制代码
post方式实现
这个相对来说按文档就可以实现,同样注意签名时参数排序问题,时间戳的问题。
请求被url为:csb地址
业务请求参数:以json或者xml或者x-www-form-urlencoded放在请求body里(如果不清楚可自行查阅webapi相关教程)
headers参数,相比get秩序以下几个
_api_timestamp:1592225468715 //时间戳
_api_name:http2http11 //服务名称
_api_signature:签名值
_api_version:1.0.0 //版本
_api_access_key: ak123 //ccess_key
Content-Type:application/x-www-form-urlencoded;charset=UTF-8
复制代码
坑点注意
- c#默认参数排序与java不一致,需要按ascll排序
- 时间戳 按unix格式获取
- get方式参数要放在url里,记得value要url编码
demo地址
© 版权声明
文章版权归作者所有,未经允许请勿转载。
THE END






















![[桜井宁宁]COS和泉纱雾超可爱写真福利集-一一网](https://www.proyy.com/skycj/data/images/2020-12-13/4d3cf227a85d7e79f5d6b4efb6bde3e8.jpg)

![[桜井宁宁] 爆乳奶牛少女cos写真-一一网](https://www.proyy.com/skycj/data/images/2020-12-13/d40483e126fcf567894e89c65eaca655.jpg)