简单的 http 通信校验(golang)

2021-08-10

通过 http 实现简单的终端和服务的通信校验。测试客户端和服务端源码通过 golang 实现。


1. 协议

协议 方法 数据格式 url
http post json http://xxxx.com/product/agent/check
  • request
1
2
3
4
5
6
7
8
9
10
11
12
{
    "client": {
        "level": "23424343", /* 用户等级。 */
        "type": "fdsfdsfa",  /* 用户类型。 */
    },
    "device" : {
        "mac": "dhsjfhjasfhjadfhjdasf", /* 设备 mac 地址,aes 加密的密文。 */
        "version": "12.34.4354"         /* 设备版本信息。 */
    },
    "time": "2010-03-13 10:00:11",       /* 时间,用于安全校验。 */
    "sign": "fhkdsahfjashfjkdshfjkdafda" /* 数字签名,用于安全校验。 */
}
  • response
1
2
3
4
5
6
7
8
9
10
11
{
    "errno": 0,      /* 错误码,默认 0 是没有错误。 */
    "errstr": "xxx", /* 错误提示,与错误码对应。 */
    "device" : {
        "mac": "dhsjfhjasfhjadfhjdasf", /* 设备 mac 地址,aes 加密的密文。。 */
        "version": "12.34.4354"         /* 设备版本信息。 */
    },
    "activation": "ewruhfdjdsahfjkhfjsirewure", /* 激活码,aes 加密的密文。 */
    "time": "2010-03-14 10:00:11",              /* 时间,用于安全校验。 */
    "sign": "fdhsjfhdasjfhjasdfhjka"            /* 数字签名,用于安全校验。 */
}

2. 安全

  • 通信安全,通过 数字签名 保证通信安全(避免通信数据在通信过程中被截获窜改)。
  • 数据安全,通过 aes 对称加密数据,避免明文传输,保证数据安全。

2.1. aes 加密

mac 信息和激活码都是通过 aes 对称加密的,密匙由客户端和服务端共同约定。协议传输的这两个数据都是密文,要获得明文,需要通过 aes 解密。

1
2
密文 = base64_encode(aes_encrypt(明文,密匙))
明文 = base64_decode(aes_decrypt(密文,密匙))

2.2. 数字签名(sign)

数字签名是一个字符串组合的校验。通过对组合数据的处理结果,对比协议传过来的 sign 数字签名是否一样。

1
sign = base64(sha1(md5(mac 密文字符串 + 盐字符串 + 时间字符串)))

3. 数据库

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
CREATE DATABASE IF NOT EXISTS lhl_product DEFAULT CHARSET utf8mb4 COLLATE utf8mb4_general_ci;

CREATE TABLE `device_info` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `device_mac` varchar(64) NOT NULL COMMENT '设备网卡 mac 地址',
  `device_version` varchar(64) NOT NULL COMMENT '请求流水 id',
  `activation` varchar(128) COMMENT '设备激活码',
  `client_type` varchar(64) NOT NULL COMMENT '用户类型',
  `client_level` varchar(64) NOT NULL COMMENT '用户等级',
  `status` tinyint(1) unsigned DEFAULT '1' COMMENT '数据状态,默认 1 有效,0 无效',
  `active_time` timestamp NULL DEFAULT CURRENT_TIMESTAMP COMMENT '激活时间',
  `create_time` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
  `update_time` timestamp NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',
  PRIMARY KEY (`id`),
  UNIQUE KEY `mac` (`device_mac`)
) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8mb4;

4. 源码

golang 实现的轻量级 http 服务,源码已放在 github

涉及到的知识点:

  • http 通信功能。
  • client / server 测试功能(client 功能server逻辑功能)。
  • 加密解密功能
  • yaml 配置文件访问功能。
  • log4go 日志功能。
  • 实现简单的 gorm 的 mysql 连接池功能。
  • 代码片段测试功能。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
func main() {
    if err := initConfig(); err != nil {
        panic(err)
    }

    runtime.GOMAXPROCS(viper.GetInt("base.maxproc"))

    log.LoadConfiguration(viper.GetString("base.log"))
    defer log.Close()

    if err := initHTTP(); err != nil {
        panic(err)
    }

    if err := initDb(); err != nil {
        panic(err)
    }

    common.InitSignal()
}

5. 后记

很长一段时间没使用 GO (golang) 了,都是边写边查,虽然比较熟悉 c/c++,现在处理一些小功能,第一时间想到的解决方案是 GO

GO 的生态强大,高质量的轮子实在太多啦 😸!语法简洁,我除了不爽它的大小写限制,其它感觉还好。

对于我,最重要的是:能少写很多代码 🥰!确认过眼神,简洁高效,强大生态,文档健全的语言:GO 确实是我的菜~