Restful 接口是 TDengine 最常用的接口,仅次于 JDBC。TDengine 支持 HTTP 和 HTTPS,但通常情况下,大家不想搞证书,又在内网环境中,采用 HTTP 方式比较多。但 HTTP 是明文传输,只要抓个包就知道账号密码了。因此需要对用户名和密码进行加密。

TDengine 支持 Basic 认证与自定义认证两种机制,下面进行简单介绍。

Basic

Basic 比较简单,就是对用户名密码进行 BASE64 编码。其实并不安全,因为可以直接对编码近解密。

示例

创建测试用户
taos> create user test pass 'P@ssw0rd';
Create OK, 0 row(s) affected (0.002246s)

taos> grant read on *.* to test;
Query OK, 0 row(s) affected (0.002141s)
对账号密码进行 Base64 加密

TDengine Restful Authorization 自定义Token-LMLPHP

使用Basic方式查询数据库
[root@c2-125 ~]# curl -L -H "Authorization: Basic dGVzdDpQQHNzdzByZA==" 127.0.0.1:6041/rest/sql -d "select current_user();"
{"code":0,"column_meta":[["current_user()","VARCHAR",11]],"data":[["test@c2-125"]],"rows":1}

自定义Token

为了提供安全性,TDengine 支持自定义Token,即对用户名密码进行特殊加密。

示例

获取自定义Token并查询
[root@c2-125 ~]# curl http://127.0.0.1:6041/rest/login/test/P@ssw0rd
{"code":0,"desc":"QIIxd+q+/t7a8qdtNZmtONryp201ma04r0sDvQTxtaDa8qdtNZmtONryp201ma04"}

[root@c2-125 ~]# curl -L -H "Authorization: Taosd QIIxd+q+/t7a8qdtNZmtONryp201ma04r0sDvQTxtaDa8qdtNZmtONryp201ma04" 127.0.0.1:6041/rest/sql -d "select current_user();"
{"code":0,"column_meta":[["current_user()","VARCHAR",11]],"data":[["test@c2-125"]],"rows":1}
特殊字符处理

以上密码比较简单,如果是复杂密码呢?

taos> alter user test pass 'P@#!$%000';
Query OK, 0 row(s) affected (0.002323s)
[root@c2-125 ~]# curl http://127.0.0.1:6041/rest/login/test/P@#!$%000
curl http://127.0.0.1:6041/rest/login/test/P@#taos%000
{"code":3,"desc":"Authentication failure"}

需要对特殊字符进行 URL编码才能传输。

[root@c2-125 ~]# curl http://127.0.0.1:6041/rest/login/test%2FP%40%23%21%24%25000
{"code":0,"desc":"QIIxd+q+/t7a8qdtNZmtONryp201ma04Uj6laakTHxe8oWCwoeYGPdryp201ma04"}

[root@c2-125 ~]# curl -L -H "Authorization: Taosd QIIxd+q+/t7a8qdtNZmtONryp201ma04Uj6laakTHxe8oWCwoeYGPdryp201ma04" 127.0.0.1:6041/rest/sql -d "select current_user();"
{"code":0,"column_meta":[["current_user()","VARCHAR",11]],"data":[["test@c2-125"]],"rows":1}

批量查询Token脚本

数据库创建好以后,DBA 会为业务创建一系列的账号,如果一个编码查询,就太没有效率了。

以下脚本会逐行读取一个文件。每行应该包含一个用户名和一个空格分隔的密码。然后脚本会将密码编码成URL格式,并向服务器发送HTTP请求,可能是为了认证并获取令牌。服务器的响应被保存到了一个临时文件中,然后脚本提取出令牌。用户名与他们对应的令牌被添加到名为 token_list.txt 的文件中。

#!/bin/sh
cat $1 |while read l
do
        uname=$(echo $l |awk '{print $1}')
        pass=$(echo $l |awk '{print $2}')
        ulpass=$(echo ${pass} | tr -d '\n' | xxd -plain | sed 's/\(..\)/%\1/g')
        curl "http://127.0.0.1:6041/rest/login/${uname}/${ulpass}" >token.tmp
        token=$(cat token.tmp |awk -F '"' '{print $6}')
        echo "$uname: $token" >> token_list.txt
done
[root@c2-125 ~]# cat userlist 
test P@#!$%000
[root@c2-125 ~]# sh getToken.sh userlist
[root@c2-125 ~]# cat token_list.txt 
test: QIIxd+q+/t7a8qdtNZmtONryp201ma04Uj6laakTHxe8oWCwoeYGPdryp201ma04
11-18 00:26