基于NodeJS的简易DDNS
无意间看到腾讯云的API文档,发现提供修改解析记录的接口。然后在想能否搭建一个非常简易的小程序,用于修改域名的解析记录呢?经过试验,是没问题的。文章的所有的代码
思路
- 使用NodeJS编写一个简易的服务端,验证来自于客户端的请求之后,然后调用腾讯的api将对应的三级域名的解析修改成最新的IP。
- 简易的流程图如下:
请求的流程图
- 实现思路。原来,我想法很简单,就直接在路由器使用脚本发起修改解析的请求。后来,我想可以做一个服务端,用于响应多个客户端的请求,可以添加或者修改解析记录,这样就可以用于多台的设备了。
- 校验请求。既然多个客户端,那么校验是需要的,所以可以使用静态文件配置token对应3级域名,或者存放与数据库中,恰好,我原本就安装了Mysql数据库,所以我就基于Mysql来存放我的配置内容吧。然后下面就是使用nodejs实现的过程了。
代码实现
!!如果你嫌麻烦,可以直接跳转代码地址。。github
调试腾讯云API
- 查看了腾讯云的API文档,发现不仅仅简单的发送参数和SecretId和SecretKey就可以了完成请求了,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 --解析出来的查询参数的keyparamSort --参数的排序(原生的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数据库(非必须,你可以把配置以及验证信息放到一个配置文件里面)。
- 初始化项目。建立文件夹,node-ddns。运行:npm init。按照常规的输入内容。入口为app.js。
- 添加依赖。根据我们需求,需要2个依赖:express(用于处理请求)、mysql(用于连接、查询mysql数据库)。运行命令:
npm install express --save npm install mysql --save
以上完成后,package.json文件大概是以下内容:
{ "name": "node-ddns", "version": "1.0.0", "description": "", "main": "app.js", "scripts": {"test": "echo \"Error: no test specified\" && exit 1" }, "author": "alan", "license": "ISC", "dependencies": {"express": "^4.16.4","mysql": "^2.17.1" } }
稍等片刻,就可以安装完毕了。如果出现错误,可以尝试使用管理员运行以上命令
- 编写测试接口,连接mysql数据库。我们在app.js可以写下代码了。引入express和mysql依赖。非常简单,内容如下,意思是程序运行在3000端口,并且有一个/test的接口,返回“测试成功”字样:
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,应用启动,然后再浏览器访问,就可以看到以下内容
建立表结构。
这里是表结构创建的语句
创建工具类
创建API文件
基于NodeJS的简易DDNS相关推荐
- 搭建基于 nodejs 的 MQTT 服务器
创建服务端 1.先从初始化一个 package.json 开始. npm init 2.安装 mqtt 服务器必要依赖项 mosca mqtt npm install mosca mqtt 3.根目录 ...
- 基于Gulp的简易前端自动化工程搭建
上个月月底在公司提出关于前后端分离的想法,并且开始研究关于前后端分离,前端工程化,模块化的一些东西,上周开始我准备自己开始写基于Gulp流的前端工程文件,这两天有时间,着手开始实现这个想法,但是写的过 ...
- Linux简易DDNS配置教程
Linux简易DDNS配置教程 DDNS与其在Linux系统上的应用 1.1 DDNS是什么,其作用是什么 DDNS(Dynamic Domain Name System,动态域名系统)是一种网络 ...
- Sequelize 4.43.0 发布,基于 Nodejs 的异步 ORM 框架
Sequelize 4.43.0 发布了,Sequelize 是一款基于 Nodejs 的异步 ORM 框架,它同时支持 PostgreSQL.MySQL.SQLite 和 MSSQL 多种数据库,很 ...
- socketserver模块用法,多道技术、 基于UDP的简易版QQ
复习 1.OSI七层2.以太网协议3.ip协议(arp协议)4.TCP5.UDP OSI七层 应表会 # 应用层 (HTTP协议, FTP协议)传输层 # 端口协议 在此层发挥作用网络层 # IP协议 ...
- [原创][连载].基于SOPC的简易数码相框 - Nios II SBTE部分(软件部分) - 从SD卡内读取图片文件,然后显示在TFT-LCD上...
实在很抱歉,时间紧张,我只讲怎样从SD卡内读取bin文件(二进制文件),然后现在TFT-LCD上. 准备工具 1. Image2Lcd.zip 操作步骤 步骤1 寻找或制作240x320的图片 简单起 ...
- 简单计算器的设计java_(基于java的简易计算器的设计.doc
(基于java的简易计算器的设计 基于java的简易计算器的设计 摘要 自从java语言诞生以来,java语言就以不可抵挡的趋势很快成为国际上广泛流行的面向对象编程语言,它既具有高级语言的特点,又少了 ...
- Sequelize 4.42.1 发布,基于 Nodejs 的异步 ORM 框架
百度智能云 云生态狂欢季 热门云产品1折起>>> Sequelize 4.42.1 发布了,Sequelize 是一款基于 Nodejs 的异步 ORM 框架,它同时支持 Pos ...
- JavaScript数据结构与算法——列表详解(下),基于Nodejs实现一个列表应用
1.上篇回顾: 上篇我们实现了一个列表类,并添加了一些属性,实现了比较多的方法,本文章将与大家一起使用列表实现一个图书借阅查询系统.需要使用JavaScript数据结构与算法--列表详解(上)中写好的 ...
最新文章
- centos 上yum命令删除还原补救方法
- python leetcode_Leetcode 常用算法 Python 模板
- 《LeetBook》leetcode题解(5):Longest Palindromic [M]——回文串判断
- 使用 Linux 15 年后,我重新回到 Windows:感觉非常糟糕
- 【Spring Cloud 系列】 二、Spring Cloud Eureka 的第一印象
- 一个五年Android开发者百度、阿里、聚美、映客的面试心经
- 香蕉树上第十一根芭蕉——vs一些操作设置
- html将英文日期格式转化为中文日期格式,excel中文日期与英文日期的转换
- 深信服研发、市场等大量岗位社招、校招内推
- ITIL 2011 -- 服务运营的5个流程简介 (上)
- Bolt: Anonymous Payment Channels for Decentralized Currencies 学习笔记
- HAproxy增加日志记录功能和自定义日志输出内容、格式
- canvas实现粒子跟随鼠标动画
- 3 在浏览器中查看请求报文和响应报文
- 【机器视觉】移动机器人控制软件的设计与实现
- scrapy导出数据
- VMware16安装过程分享
- 基于UWB的室内定位MiniFly无人机编队
- Android 子线程延时处理操作
- 各种选址、点、路线、网要求