基于NodeJS的简易DDNS

2019-04-27  本文已影响0人  dsjaikdnsajdnua

无意间看到腾讯云的API文档,发现提供修改解析记录的接口。然后在想能否搭建一个非常简易的小程序,用于修改域名的解析记录呢?经过试验,是没问题的。文章的所有的代码

思路

代码实现

!!如果你嫌麻烦,可以直接跳转代码地址。github

调试腾讯云API

代码注释里面写了注意的事项,都是有可能造成调用api失败。

/**
* 注意:
* 1. 算的签名必须要经过encodeURIComponent编码。
* 2. 检查请求的地址有没有错
* 3. 检查请求的action有没有错
* 4. 检查时间戳有没有过期
* 5. 默认为Get请求,请使用get请求。使用encodeSignature作为Signature参数
* 6. 排序的时候大小写敏感了。使用原生的排序即可
* 7. 官网例子:parseUrl("https://cns.api.qcloud.com/v2/index.php?Action=DescribeInstances&InstanceIds.0=ins-09dx96dg&Nonce=11886&Region=ap-guangzhou&SecretId=AKIDz8krbsJ5yKBZQpn74WFkmLPx3gnPhESA&SignatureMethod=HmacSHA256&Timestamp=1465185768","Gu5t9xGARNpq86cd98joQYCN3Cozk1qA",[]);、
    返回:0EEm/HtGRr/VJXTAD9tYMth1Bzm3lLHz5RCDv1GdM8s=
    编码:0EEm%2FHtGRr%2FVJXTAD9tYMth1Bzm3lLHz5RCDv1GdM8s%3D
* @param {*} url 除了Signature参数以外的get请求字符串。如:https://cns.api.qcloud.com/v2/index.php?Action=DescribeInstances&InstanceIds.0=ins-09dx96dg&Nonce=11886&Region=ap-guangzhou&SecretId=AKIDz8krbsJ5yKBZQpn74WFkmLPx3gnPhESA&SignatureMethod=HmacSHA256&Timestamp=1465185768
* @param {*} key 你的SecretId
* @param {*} result 传入一个数组。因为这里只有一个方法,需要请求加密的js,是异步的,不能将结果直接返回给你。通过数组将结果传递出去
* @returns 返回一个对象:
    {
        encodeSignature --编码后的签名(你需要的是这个)
        Signature --计算的签名
        href --你传递的地址
        param --解析出来的查询参数
        paramKeys --解析出来的查询参数的key
        paramSort --参数的排序(原生的js排序)
        paramJoins --参数的字符串
        paramJoin --
        joinAllGet --排序后的拼接请求字符串
    }
*/
function parseUrl(url, key, resultArr) {
    var addressConfig = {
        "RecordCreate": "cns.api.qcloud.com",//添加解析记录
        "RecordStatus": "cns.api.qcloud.com",//设置解析记录状态
        "RecordModify": "cns.api.qcloud.com",//修改解析记录
        "RecordList": "cns.api.qcloud.com",//获取解析记录列表
        "RecordDelete": "cns.api.qcloud.com",//删除解析记录
        "DescribeInstances": "cvm.api.qcloud.com"//查看实例列表
    };
    function _parser(url) {
        var result = {};
        var parser = document.createElement('a');
        parser.href = result.href = url;
        try {
            if (parser.search) {
                var param = parser.search.slice(1, parser.search.length);
                if (param) {
                    var paramArr = param.split("&");
                    if (paramArr) {
                        parser.param = result.param = {};
                        parser.paramKeys = result.paramKeys = paramArr.map(function (v) {
                            var vt = v.split("=");
                            parser.param[vt[0]] = result.param[vt[0]]   = vt.length === 2 ? vt[1] : "";
                            return vt[0];
                        });
                        parser.paramSort = result.paramSort = {};
                        /*1. 对参数排序 需要忽略大小写*/
                        parser.paramJoins = result.paramJoins = parser.paramKeys.sort().map(function (v) {
                            var value = decodeURIComponent(parser.param[v]);
                            parser.paramSort[v] = result.paramSort[v] = value;
                            return v + "=" + value;
                        });
                        /*2. 拼接请求字符串*/
                        parser.paramJoin = result.paramJoin = parser.paramJoins.join("&");
                        /*3. 拼接签名原文字符串 请求方法 + 请求主机 +请求路径 + ? + 请求字符串*/
                        parser.joinAllGet = result.joinAllGet = "GET" + (addressConfig[parser.param.Action]) + "/v2/index.php?" + parser.paramJoin;
                        /*4. 生成签名串*/
                        var hash = CryptoJS.HmacSHA256(parser.joinAllGet, key);
                        var hashInBase64 = CryptoJS.enc.Base64.stringify(hash);
                        parser.Signature = result.Signature = hashInBase64;
                        parser.encodeSignature = result.encodeSignature = encodeURIComponent(hashInBase64);
                    }
                }
            }
        } catch (error) {
            console.log("解析地址出错!");
            console.log(error);
        }
        return result;
    }
    $.getScript("https://cdnjs.cloudflare.com/ajax/libs/crypto-js/3.1.2/rollups/hmac-sha256.js", function () {
        $.getScript("https://cdnjs.cloudflare.com/ajax/libs/crypto-js/3.1.2/components/enc-base64-min.js", function () {
            var _result = _parser(url);
            resultArr.push(_result);
            console.log(resultArr);
        });
    });
}

如何运行这段代码呢?很简单,打开浏览器的控制台,整段复制进去,回车,会产生一个全局的方法:parseUrl。然后再在控制台调用parseUrl,参数在代码注释里面说的很清楚了,也有例子,返回的对象的encodeSignature属性就是你最终的签名值了
使用上述代码计算出签名值,然后再调用腾讯api,看看能否调试通过。通过就可以进行服务端的编写了。

服务端编码

我也很少接触nodejs。所以也写详细一点,也当做是自己的学习笔记。准备环境有:nodejs,mysql数据库(非必须,你可以把配置以及验证信息放到一个配置文件里面)。

var express = require('express');
var mysql = require("mysql");
var app = express();
var connection = mysql.createConnection({
  "host" : "111.230.165.16",
  "user" : "root",
  "password" : "alan@MYSQL!@#",
  "database" : "test"
});
connection.connect(function(err){
  if(err){
      console.log(err);
  }
});
app.get('/test',function(req,resp){
  connection.query("select 1 from dual",function(error,results,fields){
      if(error){
          resp.send('测试失败');
      }else{
          resp.send('测试成功');
      }
  });
});
app.listen(3000);
console.log("running on 3000");

运行命令:node app,应用启动,然后再浏览器访问,就可以看到以下内容

image.png
建立表结构。

这里是表结构创建的语句

表结构用于存放验证信息(ddns_user)和腾讯的token。
创建工具类
创建API文件
上一篇 下一篇

猜你喜欢

热点阅读