[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
    }
}

我就只能幫你到這了,剩下的就看你自己了

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章