文档中心>实时互动-工业能源版>开发指南>免注册登录与临时会话授权

免注册登录与临时会话授权

最近更新时间:2025-12-11 16:48:01

我的收藏
说明:
免注册登录与观看授权,可不需要预先对设备进行创建,基于项目共享密钥生成设备密钥进行登录和自动注册,并可选择会话设备进行临时授权。其安全性略低于设备独立密钥方式,但由于不需要预先注册,适合希望简化业务流程的客户。

开通项目共享密钥

通过云 API 接口 修改项目安全模式 开启项目共享密钥,设置32位项目密钥,并根据使用场景设置是否允许自动注册以及远端获取现场设备列表。
字段
说明
取值
Mode
安全模式
0:关闭项目共享密钥
1:开启项目共享密钥
Key
项目共享密钥
32位字符串,小写英文 + 数字
AutoRegister
自动注册方式
0:关闭自动注册
1:仅允许现场设备自动注册
2:仅允许远端设备自动注册
3:允许现场和远端设备均自动注册
FieldListEnable
是否允许远端获取现场设备列表(getGwList)
0:不允许
1:允许
注意:
开启项目共享密钥后,请注意保护项目共享密钥,并及时更新。建议项目共享密钥保存在服务器侧。由服务器生成设备登录密码下发给设备,避免密钥保存在客户端侧产生的密钥泄露风险。
开启项目共享密钥后,对于已注册的设备,仍可使用原设备密码登录。若希望仅能通过共享密钥生成密码登录,请通过云 API 将设备密码更新为"USEPROJECTKEYPWD"。
如果设备数量较多,使用时建议关闭自动注册和现场设备列表。

设备登录密码生成

开启项目共享密钥后,服务允许设备采用基于项目共享密钥生成的设备密码登录。可基于设备 ID 以及项目共享密钥生成设备密码,具体计算方法如下:
Python
Go
Java
JS
import hmac
import hashlib
import base64
def 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-SHA256
Mac mac = Mac.getInstance("HmacSHA256");
mac.init(secretKeySpec);
String data = devId + expiretime.toString();
// 执行 HMAC-SHA256 计算
byte[] hmacBytes = mac.doFinal(data.getBytes());
// 转base64
String 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-SHA256
const 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 对应的白名单设置,会造成远端设备没有权限观看现场设备。此时需要基于项目共享密钥生成会话授权码,并将授权码分发给远端设备。远端设备通过会话授权接口设置授权码可获得对应的临时会话权限。具体会话授权码生成的计算方法如下:
Python
Go
Java
JS
import hmac
import hashlib
import base64
def 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-SHA256
Mac mac = Mac.getInstance("HmacSHA256");
mac.init(secretKeySpec);
String data = remoteDevId + fieldDevId + expiretime.toString();
// 执行HMAC-SHA256计算
byte[] hmacBytes = mac.doFinal(data.getBytes());
// 转base64
String 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-SHA256
const 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 和共享密钥生成的登录密码登录,拉取目标现场设备视频流。如果项目设置为白名单模式,约束远端对现场设备视频的观看权限,则还需基于共享密钥生成临时观看授权给远端设备。

批量密码变更

场景需求:
服务端希望能够一次更新所有设备密码,无需单个设备更新。
用法建议:
开启共享密钥模式并关闭设备注册,定期更改项目共享密钥,实现批量密码更新。