说明:
免注册登录与观看授权,可不需要预先对设备进行创建,基于项目共享密钥生成设备密钥进行登录和自动注册,并可选择会话设备进行临时授权。其安全性略低于设备独立密钥方式,但由于不需要预先注册,适合希望简化业务流程的客户。
开通项目共享密钥
字段 | 说明 | 取值 |
Mode | 安全模式 | 0:关闭项目共享密钥 1:开启项目共享密钥 |
Key | 项目共享密钥 | 32位字符串,小写英文 + 数字 |
AutoRegister | 自动注册方式 | 0:关闭自动注册 1:仅允许现场设备自动注册 2:仅允许远端设备自动注册 3:允许现场和远端设备均自动注册 |
FieldListEnable | 是否允许远端获取现场设备列表(getGwList) | 0:不允许 1:允许 |
注意:
开启项目共享密钥后,请注意保护项目共享密钥,并及时更新。建议项目共享密钥保存在服务器侧。由服务器生成设备登录密码下发给设备,避免密钥保存在客户端侧产生的密钥泄露风险。
开启项目共享密钥后,对于已注册的设备,仍可使用原设备密码登录。若希望仅能通过共享密钥生成密码登录,请通过云 API 将设备密码更新为"USEPROJECTKEYPWD"。
如果设备数量较多,使用时建议关闭自动注册和现场设备列表。
设备登录密码生成
开启项目共享密钥后,服务允许设备采用基于项目共享密钥生成的设备密码登录。可基于设备 ID 以及项目共享密钥生成设备密码,具体计算方法如下:
import hmacimport hashlibimport base64def genDevicePassword(devId,Key,expiretime):content = devId+str(expiretime)hmac_digest = hmac.new(Key.encode('utf-8'), content.encode('utf-8'), hashlib.sha256).digest()base64_str = base64.b64encode(hmac_digest).decode('utf-8')signature = base64_str.replace('+','').replace('/','').replace('=','')return signature+"_"+str(expiretime);
import ("crypto/hmac""crypto/sha256""encoding/base64""fmt""strings")func GenDevicePassword(devid, secKey string, expiretime int64) string {h := hmac.New(sha256.New, []byte(secKey))h.Write([]byte(fmt.Sprintf("%s%d", devid, expiretime))digest := h.Sum(nil)encoded := base64.StdEncoding.EncodeToString(digest)encoded = strings.ReplaceAll(encoded, "+", "")encoded = strings.ReplaceAll(encoded, "/", "")encoded = strings.ReplaceAll(encoded, "=", "")return encoded+fmt.Sprintf("_%d",expiretime)}
import javax.crypto.Mac;import javax.crypto.spec.SecretKeySpec;import java.util.Base64;public class DeviceTokenGenerator {public static String genToken(String key, String devId, Long expiretime) {try {// 创建一个 HmacSHA256 密钥SecretKeySpec secretKeySpec = new SecretKeySpec(key.getBytes(), "HmacSHA256");// 获取 Mac 对象来执行 HMAC-SHA256Mac mac = Mac.getInstance("HmacSHA256");mac.init(secretKeySpec);String data = devId + expiretime.toString();// 执行 HMAC-SHA256 计算byte[] hmacBytes = mac.doFinal(data.getBytes());// 转base64String encoded = Base64.getEncoder().encodeToString(hmacBytes);// 去除 + 和/,转小写return encoded.replace('+', '').replace('/','').replace('=','') + "_" + expiretime.toString();} catch (Exception e) {e.printStackTrace();}return "";}}
async function genDevicePassword(devId, key, expiretime) {// 1. 准备数据const content = devId + expiretime.toString();const encoder = new TextEncoder();const keyData = encoder.encode(key);const contentData = encoder.encode(content);// 2. 生成 HMAC-SHA256const cryptoKey = await window.crypto.subtle.importKey("raw",keyData,{ name: "HMAC", hash: "SHA-256" },false,["sign"] );const signature = await window.crypto.subtle.sign("HMAC",cryptoKey,contentData );// 3. Base64 编码并处理特殊字符const base64 = btoa(String.fromCharCode(...new Uint8Array(signature)));const cleaned = base64.replace(/\\+/g, '').replace(/\\//g, '').replace(/=/g, '');return `${cleaned}_${expiretime}`;}
注意:
用于生成密码的
devId 字符串中带有项目 ID 前缀,格式为:{项目 ID} / {设备 ID}。为保证其他功能可用性,设备 ID 建议与设备创建 API 要求一致,由小写英文、数字和下划线构成,长度不超过18位。密码过期时间戳精度为分钟,等于过期时刻 UNIX 时间戳(秒) / 60,长度为8位。设备登录时,当服务器时间超过过期时间戳,设备密码将失效。
设备初始化时,可使用上述生成的设备密码作为 password 进行登录。
会话授权码生成
免注册登录时,若项目设置为白名单模式,而服务端并没有设备 ID 对应的白名单设置,会造成远端设备没有权限观看现场设备。此时需要基于项目共享密钥生成会话授权码,并将授权码分发给远端设备。远端设备通过会话授权接口设置授权码可获得对应的临时会话权限。具体会话授权码生成的计算方法如下:
import hmacimport hashlibimport base64def genSessionAuthCode(remoteDevId,fieldDevId,Key,expiretime):content = remoteDevId+fieldDevId+str(expiretime)hmac_digest = hmac.new(Key.encode('utf-8'), content.encode('utf-8'), hashlib.sha256).digest()base64_str = base64.b64encode(hmac_digest).decode('utf-8')signature = base64_str.replace('+','').replace('/','').replace('=','')return signature+"_"+str(expiretime);
import ("crypto/hmac""crypto/sha256""encoding/base64""fmt""strings")func GenSessionAuthCode(remoteDevId, fieldDevId, secKey string, expiretime int64) string {h := hmac.New(sha256.New, []byte(secKey))h.Write([]byte(fmt.Sprintf("%s%s%d",remoteDevId,fieldDevId,expiretime)))digest := h.Sum(nil)encoded := base64.StdEncoding.EncodeToString(digest)encoded = strings.ReplaceAll(encoded, "+", "")encoded = strings.ReplaceAll(encoded, "/", "")encoded = strings.ReplaceAll(encoded, "=", "")return encoded+fmt.Sprintf("_%d",expiretime)}
import javax.crypto.Mac;import javax.crypto.spec.SecretKeySpec;import java.util.Base64;public class SessionAuthCodeGenerator {public static String genAuthCode(String key, String remoteDevId, String fieldDevId, Long expiretime) {try {// 创建一个HmacSHA256密钥SecretKeySpec secretKeySpec = new SecretKeySpec(key.getBytes(), "HmacSHA256");// 获取Mac对象来执行HMAC-SHA256Mac mac = Mac.getInstance("HmacSHA256");mac.init(secretKeySpec);String data = remoteDevId + fieldDevId + expiretime.toString();// 执行HMAC-SHA256计算byte[] hmacBytes = mac.doFinal(data.getBytes());// 转base64String encoded = Base64.getEncoder().encodeToString(hmacBytes);// 去除 + 和/,转小写return encoded.replace('+', '').replace('/','').replace('=','') + "_" + expiretime.toString();} catch (Exception e) {e.printStackTrace();}return "";}}
async function genSessionAuthCode(remoteDevId,fieldDevId,Key,expiretime) {// 1. 准备数据const content = remoteDevId + fieldDevId + expiretime.toString();const encoder = new TextEncoder();const keyData = encoder.encode(key);const contentData = encoder.encode(content);// 2. 生成 HMAC-SHA256const cryptoKey = await window.crypto.subtle.importKey("raw",keyData,{ name: "HMAC", hash: "SHA-256" },false,["sign"] );const signature = await window.crypto.subtle.sign("HMAC",cryptoKey,contentData );// 3. Base64 编码并处理特殊字符const base64 = btoa(String.fromCharCode(...new Uint8Array(signature)));const cleaned = base64.replace(/\\+/g, '').replace(/\\//g, '').replace(/=/g, '');return `${cleaned}_${expiretime}`;}
注意:
用于生成授权码的远端设备和现场设备 ID 字符串中均带有项目 ID 前缀,格式为
{项目 ID}/{设备 ID}。授权码过期时间戳的精度为分钟,等于过期时刻 UNIX 时间戳(秒) / 60,长度为8位。当服务器时间超过授权码的过期时间,会话授权将失效。远端设备设置会话授权码
远端设备可通过 TRRO_setSessionPermissionToken 接口设置临时会话授权。一个会话授权码,用于一对远端设备和现场设备的会话授权。远端设备可针对不同的现场设备设置不同的会话授权码。针对同一个现场设备,后设置的临时会话授权将覆盖之前设置的。
/** @name : TRRO_setSessionPermissionToken* @brief : 项目白名单模式下,未设置白名单的设备,需要通过会话授权码才能观看* @input : fieldDevId 目标现场设备 ID,格式为项目ID/设备ID* authcode 授权码* expiretime 授权码过期时间戳,精度为分钟* @return : 成功 1 失败 <= 0*/int TRRO_setSessionPermissionToken(const char* fieldDevId, const char* authcode);
参数 | 含义 |
fieldDevId | 目标现场设备 ID。 |
authcode | 授权码,需要基于项目共享密钥生成。 |
返回值 | 成功:1 。 失败:<= 0。 |
典型使用场景
免注册接入
场景需求:
无需提前对设备进行注册,设备使用项目密钥即可完成首次上线。
用法建议:
开启项目共享密钥。设备首次登录时,基于项目共享密钥生成的登录密码上线。
免注册观看
场景需求:
远端设备无需注册,即可观看视频流,适合临时观看。
用法建议:
开启项目共享密钥,并关闭自动注册以及远端现场设备列表获取功能。对于远端设备,可使用临时生成的远端设备 ID 和共享密钥生成的登录密码登录,拉取目标现场设备视频流。如果项目设置为白名单模式,约束远端对现场设备视频的观看权限,则还需基于共享密钥生成临时观看授权给远端设备。
批量密码变更
场景需求:
服务端希望能够一次更新所有设备密码,无需单个设备更新。
用法建议:
开启共享密钥模式并关闭设备注册,定期更改项目共享密钥,实现批量密码更新。