[QDB]TQHttpProvider 通讯协议说明

TQHttpProvider 服务器端使用任何语言编写都可以,但需要其支持 HTTP/HTTPS 协议。

要使用 TQHttpProvider,您需要设置 TQHttpProvider 的以下属性:

  1. ServiceUrl:该 URL 会被用做对服务器端请求的基准地址来使用,下面是对应的子URL:
    (1)、Open:该命令用于打开一个数据库连接
    (2)、Close:关闭当前打开的数据库连接
    (3)、OpenDataSet:打开一个数据集对象
    (4)、ExecSQL:执行一个不返回结果集的 SQL 脚本
    (5)、RefreshToken:用于刷新当前令牌,避免令牌过期
  2. AppId:客户端应用的唯一编码,用来唯一标记一个应用。服务器端应根据这个 appid,去查找对应的  MD5  签名时使用的盐值,以便验证参数是否是有效的参数,以避免被外部调用。
  3. AppSalt:AppId 对应的用于计算 MD5 哈希值的盐值,用于混淆签名内容。

使用以上代码以后,您就可以按照 QDB 的正常规则使用 TQHttpProvider 访问服务器端的数据库了。那么,接下来的问题就是客户端与服务器端通讯的协议具体约定了:

1、建立连接

命令代码:/Open

命令参数:

  • appid :对应于 TQHttpProvider.AppId 属性
  • timestamp:当前计算机的时间戳,后续服务器端可以根据该值与服务器时间的差值,来确定是否来自应用的访问,从而避免外部攻击
  • database:要连接的数据库的连接字符串,一般来说,为了避免传递敏感信息,应在服务器端定义别名,这里直接传连接的别名,由服务器端进行解析,获取实际的连接参数。
  • sign:参数签名,其具体算法是按不区分大小写的参数名称排序,也就是说 AppId 和 appid 计算排序列的位置应该是一样的,然后将各个参数拼接成未进行 URL 编码的字符串,参数名与值之前使用等号连接,参数与参数之间使用 “&” 连接。拼接后的参数字符串 + TQHttpProvider.AppSalt 的值计算 MD5 哈希值并以小写方式赋值给 sign。

返回值:

服务器端应返回一个符合下面格式要求的 JSON 对象:

{
"code":0,//整数错误代码,0 代表成功,其它值意味着失败,具体含义定义由服务器端实现确定
"hint":"",//错误提示消息字符串,如果操作成功,该项被忽略,也就是可以不返回,一般用于提示用户
"help":"",//提供给开发者的出错帮助信息,可能会包含敏感信息,不适宜提供给用户呈现
"result":{
  "access_token":"",//会话令牌,后续操作都需要提供该令牌以确定您的信息
  "access_expire":7200,//会话有效期,超过有效期,会话需要刷新令牌或者重新打开连接
  "refresh_token":"",//刷新令牌,该令牌用于给当前会话“续命”,调用 /RefreshToken 时需要传递该参数
  "refresh_expire":2592000//刷新令牌有效期,应大于会话的有效期
  }
}

您也可以通过服务器在 result 里返回额外的参数给客户端,整个 result 的内容会被记录到 ServerExtParams 属性中。

示例 URL:

https://blog.qdac.cc/qdb/qdb_httppov.php/Open?timestamp=1522357751&sign=b67d447f3cc86b8c1e69368ddb355671&appid=Demos.HttpProvider&database=PgSQLDemo

额外建议:

对于有特殊需要的客户,端参数签名算法可以自定义,可以修改 TQHttpProvider.Rest 函数来完成这一工作。

2、关闭连接

命令代码:/Close

命令参数:

  • token:建立连接时得到的会话令牌( access_token )
  • timestamp:当前计算机的时间戳
  • sign:参数签名,参考 /Open 命令

返回值:

服务器端应返回一个符合下面格式要求的 JSON 对象:

{
"code":0,//整数错误代码,0 代表成功,其它值意味着失败,具体含义定义由服务器端实现确定
"hint":"",//错误提示消息字符串,如果操作成功,该项被忽略,也就是可以不返回,一般用于提示用户
"help":""//提供给开发者的出错帮助信息,可能会包含敏感信息,不适宜提供给用户呈现
}

备注:

无论服务器返回错误代码是何值,都不会影响连接关闭。

示例 URL:

https://blog.qdac.cc/qdb/qdb_httppov.php/Close?token=se3hKEXp0vsqsZgNcSXUqRzcvb6IGBuj&sign=8e9ea60b0cfac8c1b5032fecc71afa98&timestamp=1522357651

3、打开数据集

命令代码:/OpenDataSet

命令参数:

  • token:建立连接时得到的会话令牌( access_token )
  • timestamp:当前计算机的时间戳
  • sign:参数签名,参考 /Open 命令
  • sql:要查询的 SQL 脚本。如果使用 POST 方式投递,那么它将做为一个 Json 对象的子结点存在,否则当做普通参数参与签名计算。
  • transaction:是否需要开启事务,布尔值。如果使用 POST 方式投递,那么它将做为一个 Json 对象的子结点存在,否则当做普通参数参与签名计算。
  • params:SQL 参数与值对列表,仅 POST  方式下需要。GET 方式下,参数被直接通过 URL 传递。

返回值:

{
"code":0,//整数错误代码,0 代表成功,其它值意味着失败,具体含义定义由服务器端实现确定
"hint":"",//错误提示消息字符串,如果操作成功,该项被忽略,也就是可以不返回,一般用于提示用户
"help":"",//提供给开发者的出错帮助信息,可能会包含敏感信息,不适宜提供给用户呈现
"result":{
  "Fields":[//字段定义列表
     {
     "name":"",//字段名
     "table":"",//字段所属表名,非必需
     "schema":"",//表所有者,非必需
     "category":"",//数据库,非必需
     "base_name":"",//数据库原始字段名,非必需
     "delphi_type":"",//对应的 Delphi 字段类型,值参考 FieldTypeNames 定义,必需
     "len":0,//对应的列长度,非必需
     "precision":0,//精度,非必需
     "scale":0,//小数点后位数,非必需
     "flags":[not_null,primary_key,multiple_key,unique_key,blob]//非必需
     }...
     ]
  "Records":[//记录列表
     []//值列表数组
     ,...
     ]
  }
}

备注:

1、使用 POST 传递 SQL 命令时,JSON 参数格式示例如下:

{
"sql":"select * from information_schema.columns where table_name=:tablename",
"transaction":false,
"params":{
   "tablename":"pg_indexes"
   }
}

2、出于安全考虑,一般不推荐在客户端直接传递 SQL 脚本到服务器端执行。可以使用预定义SQL脚本,然后传别名及参数的方式,执行相应的结果集,具体参考 qdb_httpprov.php 实现。

参考 URL:

https://blog.qdac.cc/qdb/qdb_httppov.php/OpenDataSet?token=QWPRU15npVEzTlvR7kdU9sF7BRsbKQdl&timestamp=1522357912&sign=af03500cb0fd5892a302611deffeabf9

4、执行SQL脚本

命令代码:/ExecSQL

参数:

  • token:建立连接时得到的会话令牌( access_token )
  • timestamp:当前计算机的时间戳
  • sign:参数签名,参考 /Open 命令
  • sql:要查询的 SQL 脚本。如果使用 POST 方式投递,那么它将做为一个 Json 对象的子结点存在,否则当做普通参数参与签名计算。
  • transaction:是否需要开启事务,布尔值。如果使用 POST 方式投递,那么它将做为一个 Json 对象的子结点存在,否则当做普通参数参与签名计算。
  • params:SQL 参数与值对列表,仅 POST  方式下需要。GET 方式下,参数被直接通过 URL 传递。

返回值:

{
"code":0,//整数错误代码,0 代表成功,其它值意味着失败,具体含义定义由服务器端实现确定
"hint":"",//错误提示消息字符串,如果操作成功,该项被忽略,也就是可以不返回,一般用于提示用户
"help":"",//提供给开发者的出错帮助信息,可能会包含敏感信息,不适宜提供给用户呈现
"result":0//最后的SQL语句影响的行数
}

备注:

1、使用 POST 传递 SQL 命令时,JSON 参数格式示例如下:

{
"sql":"select * from information_schema.columns where table_name=:tablename",
"transaction":false,
"params":{
   "tablename":"pg_indexes"
   }
}

2、出于安全考虑,一般不推荐在客户端直接传递 SQL 脚本到服务器端执行。可以使用预定义SQL脚本,然后传别名及参数的方式,执行相应的结果集,具体参考 qdb_httpprov.php 实现。

分享到: