腾讯云API使用实例——添加云解析
概述
为什么会产生这个需求呢?云解析一般不是直接绑域名就行了吗?别人用API一般都是操作云主机,云存储等等的,没想到我第一次自己去看云服务API,照文档操作竟然是为了操作云解析。
好了,废话不多说,原因是这样的:由于博主大学快要毕业了,云服务器这东西你是知道的,学生的时候有个学生价,虽然配置烂了点吧(1核 2G 40G/50G 1Mbps/1000G Max5Mbps)这样的配置的机器也就搭个个人博客还是非常有用的,有时候百度云传不了的资源也可以暂时用这个传。但是一旦没有了学生优惠,这个配置的机器一年你要我2000多,虽然除了硬件配置还有全天开机,不怕出错,固定公网IP这些开销,但是相信一般从大学刚走向社会的人是不愿意掏这个钱的,那就自己搭个吧,看这个配置应该也不贵。
上淘宝一看,一下就相中了两款机器,一款是j5005的,一款是j4105的,这两个都是Intel18年的赛扬低功耗桌面U,主频max差不多都是2.5GHz左右,TDP10W,这种配置带个博客轻轻松松,而且一天开机也费不了多少电,不过j5005那个有点贵,于是就选了j4105这个,1000少一点(半年回本,一年大赚)。4G内存60G硬盘。其实还有一个潜在的因素为什么不选这个价位主频较高的i3,就是这个U它支持4K60Hz的显示输出,而我刚刚买了个4K屏。
这样所需要的只是一个固定的ip,校园网有TM固定ip,全是临时租来的,于是就想着每天来电了以后让机器自动将当前IP加到云解析去,这样也能凑凑合合弄个博客。
实现
弄这个东西如果不仔细总会有一些奇奇怪怪的问题,我就是因为种种问题从昨晚一直弄到了今天中午。
原文链接 签名方法 请求结构简介
- 首先,便是c#和php的许多形似函数得到结果不同的问题,比如unix时间戳函数,md5加密算法,sha等加密算法。好在你找到了这篇博客,不然网上那些还要你找几个才能凑出来一个对的,唉谁让php是最好的语言呢,服务器用,你c#就得自己调整呗。
- 腾讯云要求对请求参数对进行排序后计算密文,排序是按照Ascii续,而不是字母序,一开始还把大小写位置弄错了一回。
- 使用POST的时候,不用对参数进行url编码,因为POST的数据是在表单中发送的,GET的数据是在URL中发送的所以要对参数进行URL编码。
- POST请求一定要有x-www-form-urlencoded头
代码
测试 2019-3-18 可用
///------------------------------------------------------------------------------
/// @ Y_Theta
///------------------------------------------------------------------------------
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net.Http;
using System.Security.Cryptography;
using System.Text;
using System.Threading.Tasks;
using System.Web;
/// <summary>
/// 腾讯云解析API
/// </summary>
namespace TencentCloudAPI_DNR {
internal class API_DNR {
#region Properties
/// <summary>
/// 用于post的代理
/// </summary>
private HttpClient _client;
private const string _url = "https://cns.api.qcloud.com";
/// <summary>
/// 在 云API密钥 上申请的标识身份的 SecretId,一个 SecretId 对应唯一的 SecretKey , 而 SecretKey 会用来生成请求签名 Signature。具体可参考 签名方法 章节。
/// </summary>
private const string _secretId = "********";
private const string _secretKey = "********";
//to test the whether the hmacSHA256 is wrong
//private const string _secretKey = "Gu5t9xGARNpq86cd98joQYCN3Cozk1qA";
#region common arguments
/// <summary>
/// 操作 必须参数
/// </summary>
private string _action;
/// <summary>
/// 当前 UNIX 时间戳,可记录发起 API 请求的时间。
/// </summary>
private string _time;
/// <summary>
/// 随机正整数,与 Timestamp 联合起来, 用于防止重放攻击。
/// </summary>
private string _nonce;
/// <summary>
/// 请求签名,用来验证此次请求的合法性,需要用户根据实际的输入参数计算得出。计算方法可参考 签名方法 章节。
/// </summary>
private string _signature;
/// <summary>
/// 签名方式,目前支持 HmacSHA256 和 HmacSHA1。只有指定此参数为 HmacSHA256 时,才使用 HmacSHA256 算法验证签名,其他情况均使用 HmacSHA1 验证签名。详细签名计算方法可参考 签名方法 章节。
/// </summary>
private string _signatureMethod;
#endregion
#endregion
#region Methods
public void InitClient() {
_client = new HttpClient(new HttpClientHandler { UseCookies = true });
_client.DefaultRequestHeaders.Add("user-agent", "Mozilla/5.0 (Windows NT 6.1; Win64; x64; rv:57.0) Gecko/20100101 Firefox/57.0");
_client.DefaultRequestHeaders.Add("Connection", "Keep-Alive");
_client.DefaultRequestHeaders.Add("Keep-Alive", "timeout=600");
_client.DefaultRequestHeaders.Add("ContentType", "application/x-www-form-urlencoded");
_client.BaseAddress = new Uri(_url);
}
/// <summary>
/// 添加解析
/// </summary>
/// <param name="domain"></param>
/// <param name="subDomain"></param>
/// <param name="recordType"></param>
/// <param name="value"></param>
/// <param name="recordLine"></param>
/// <param name="ttl"></param>
/// <param name="mx"></param>
/// <returns></returns>
public async Task<string> AddReslotion(string domain, string subDomain, string recordType, string value, string recordLine = "默认") {
return await Task<string>.Run(() => {
_time = UNIX_TimeStamp();
_nonce = new Random().Next().ToString();
_signature = hmacSHA256($"POSTcns.api.qcloud.com/v2/index.php?Action=RecordCreate&Nonce={_nonce}&SecretId={_secretId}&SignatureMethod=HmacSHA256&Timestamp={_time}&domain={domain}&recordLine={recordLine}&recordType={recordType}&subDomain={subDomain}&value={value}", _secretKey);
var respond = _client.PostAsync("/v2/index.php",
new FormUrlEncodedContent(new List<KeyValuePair<string, string>> {
new KeyValuePair<string, string>("Timestamp",_time),
new KeyValuePair<string, string>("Nonce",_nonce),
new KeyValuePair<string, string>("SecretId",_secretId),
new KeyValuePair<string, string>("Signature",_signature),
new KeyValuePair<string, string>("SignatureMethod","HmacSHA256"),
new KeyValuePair<string, string>("Action","RecordCreate"),
new KeyValuePair<string, string>("domain",domain),
new KeyValuePair<string, string>("subDomain",subDomain),
new KeyValuePair<string, string>("recordLine",recordLine),
new KeyValuePair<string, string>("recordType",recordType),
new KeyValuePair<string, string>("value",value),
})).Result;
//如果你使用GET就将上面的参数再过一遍UrlEncode,然后直接拼url
return respond.Content.ReadAsStringAsync().Result;
});
}
/// <summary>
/// 获取UNIX格式的时间戳
/// </summary>
private string UNIX_TimeStamp() {
DateTime startTime = TimeZone.CurrentTimeZone.ToLocalTime(new System.DateTime(1970, 1, 1));
return ((int)(DateTime.Now - startTime).TotalSeconds).ToString();
}
/// <summary>
/// php hash_hmac utf8
/// </summary>
/// <param name="data">加密文本</param>
/// <param name="key">密钥</param>
static string hmacSHA256(String data, String key) {
using (HMACSHA256 hmac = new HMACSHA256(Encoding.UTF8.GetBytes(key))) {
return Convert.ToBase64String(hmac.ComputeHash(Encoding.UTF8.GetBytes(data))).Replace("-", "");
}
}
/// <summary>
/// 获取使用于腾讯服务器的url编码字符
/// </summary>
public string UrlEncode(string str) {
StringBuilder builder = new StringBuilder();
foreach (char c in str) {
if (HttpUtility.UrlEncode(c.ToString()).Length > 1) {
builder.Append(HttpUtility.UrlEncode(c.ToString()).ToUpper());
}
else {
builder.Append(c);
}
}
return builder.ToString();
}
#endregion
#region Constructors
public API_DNR() {
InitClient();
}
#endregion
}
}
我就只能帮你到这了,剩下的就看你自己了