令牌(Token)
基于安全性考虑,通过外部链接 VDN 的 Web API 或者消息服务时,可以使用令牌安全机制。
基本流程
使用 VDN 的令牌简单概括为:
1、通过外部服务器端向服务器端发出请求获取令牌(Token)
2、在前台请求中携带令牌(Token)访问 VDN
令牌设置

【系统设置】-【Web】-【Web 设置】-【令牌设置】关于令牌共有三个选项
令牌标识 获取令牌后通过 Header 或者 URL 传递令牌时所使用的标识名称,默认为:Token;注意使用 URL 传递时必须都为小写(设置值可以存在大写)
TokenKey 获取令牌时使用的 Key 值
URL 传输 是否允许通过 URL 传输令牌值
VDN 中决定是否使用令牌的设置主要有两处:

- 【PB 插件】项目发布时,【扩展属性】-【身份验证】选择令牌访问,这样外部通过 Web API 访问该 PB 插件时就需要使用令牌。

- 【系统设置】-【Web】-【Web 设置】-【WebSocket】 节点下,选中【验证令牌】,则外部连接 VDN 消息服务(WebSocket)时,就需要使用令牌
获取令牌
通过第三方系统的服务器端后台代码以 Get/Post 方式从 VDN 服务器获取 Token,然后返回给前台请求使用时携带,以合法访问 VDN WebAPI 或消息服务。
示例代码
Example\Web功能\Source\获取令牌 目录下提供的 C#的演示代码
/// <summary>
/// GetToken 获取令牌
/// </summary>
/// <returns>返回的Token,如果为error开头则代表发生错误,格式error/msg</returns>
protected string GetToken(ref string asError)
{
try
{
//TokenKey VDN高级设置中所设置
string sTokenKey = "TokenKey";
//1、获取服务器的unix时间戳
string sTim = Common.GetUnix().ToString();
//2、加密时间戳生成新Key
string sNewKey = Common.Encrypt(sTim, sTokenKey);
//3、申请操作GetToken,使用sNewKey加密
string sAction = Server.UrlEncode(Common.Encrypt("GetToken", sNewKey).Replace("/", "^/"));
//4、向服务器申请,支持Get/Post 参数格式: method=VDNSys¶ms=sAction/sTim{/once}
string sToken = Common.HttpGet("http://192.168.2.189:8100/api", "method=VDNSys¶ms=" + sAction + "/" + sTim, Request.Url.ToString(), Request.UserAgent);
//判断长度
if (sToken.Length == 0)
{
asError = "未成功获取Token";
}
//判断是否以error开头
if (sToken.Length > 5 && sToken.Substring(0, 5) == "error")
{
asError = sToken.Substring(6);
return "";
}
//5、处理Token,先使用sNewKey解密获取原值
sToken = Common.Decrypt(sToken, sNewKey);
//6、再使用使用sTokenKey加密获取最终的Token
sToken = Common.Encrypt(sToken, sTokenKey);
return sToken;
}
catch (Exception ex)
{
asError = ex.Message;
}
return "";
}流程
获取服务器的 unix 时间戳(是从 1970 年 1 月 1 日(UTC/GMT 的午夜)开始所经过的秒数),该时间同 VDN 服务器时间差不能超过 Session 超时时间(默认 2 小时)
以 TokenKey 为 Key,对时间戳进行 DES 加密,做为后面加密的新 Key,这里称为 NewKey
以 NewKey 为 Key 对字符串"GetToken"加密作为参数method 的值
使用 Get 方式或者 Post(URLEncoded 格式)需要对该值进行UrlEncode编码
通过 Get\Post 方式向服务器发送请求,获取令牌(Token),请求格式见【参数格式】
判断返回值,为空则代表获取失败;当以 error 开头时,则返回内容包含错误信息
使用 NewKey 对返回值进行解密,获取令牌(Token)的原值
使用 TokenKey 对原值进行加密获取最终的令牌(Token)值
DES 加密
获取令牌需要用到 DES 加密,模式如下:
des.Mode = CipherMode.CBC;
des.Padding = PaddingMode.PKCS7;
参数格式
Get 方式获取:
http://www.\*\*\*\*.net:8088/api?method=VDNSys¶ms=byKN1VuEWwG4iIu3ovDQmA==/1506324850/oncePost 方式获取:
{"method":"VDNSys","params":["sZHx^/gNTmpoM^/IPZjV8lBw==","1506331318","once"]} method=VDNSys¶ms=4JbWItEsS^/rNbk+VKsl2iQ==/1506334187/once| 参数 | 值 | 说明 |
|---|---|---|
| method | VDNSys | 固定值,用于 VDN 确认操作 |
| params | action /Unix 时间戳/once |
HttpWebRequest 属性设置
| 属性 | 值 | 说明 |
|---|---|---|
| Referer | 来源站点 URL 值 例如: http://www.xxx.com/ | 非必须,当 VDN 服务器端【高级设置】-【Web API】-【验证来源】选中了,则该值符合来源设置列表中的规则,否则无法获取。 可以设置为:Request.Url.ToString() 或者请求发出站点的 URL 值 |
| UserAgent | 客户端的 UserAgent 值 Request.UserAgent | 非必须,如果设置了该值,VDN 会对之后使用该令牌的请求都进行验证,判断 UserAgent 是否和获取令牌时的值一致,这样安全性会更高一些。 |
| ContentType | text/html;charset=UTF-8 :Get 方式获取 application/json :Post 方式获取,内容为 JSON 格式 application/x-www-form-urlencoded :Post 方式获取,内容为 URLEncoded 格式 |
使用令牌
URL 传递
通过 URL 参数传递,多用于 Get 方式及基于 WebSocket 的消息服务,示例:
http://192.168.2.189:8100/api?method=\[pbplugin\].f\_good¶ms=a1/a2&format=json&token=ErjmvIE6T6dLuBb%2fK7akm1注意
这里的标示符[token]必须为小写,即使设置值为:Token 这里也要使用: token
通过 URL 传递令牌时需对令牌值进行UrlEncode编码
WebSocket也是通过 URL 参数传递:
var ws = new WebSocket("http://www.xxx.net:8088/ws?token-%2bSTt0cikCaTfrcl3mNdz4SEl8");
ws.onopen = function (e) {
login(ws);
};Header 传递
通过 Header 传递,使用 POST 或者 Get 方式调用 WebAPI 时都可以通过 Header 传递令牌,示例:

