[C#] 腾讯云API使用实例——添加云解析

腾讯云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
    }
}

我就只能帮你到这了,剩下的就看你自己了

猜你喜欢

转载自blog.csdn.net/q886yes/article/details/88642180