1、 Environmental preparation
Install the platform and download the server -E
2、 Preparation before development
Before development, it is necessary to obtain the identity authentication information (AppId/AppKey) of the docking, and the platform will verify the identity of the request sender through the (AppId/AppKey) authentication method. AppId and AppKey are created in the operation management center of the platform after installation, as shown in the following figure.
3、 Docking development
1. Token generation
randNum = randInt() % 900000 + 100000
sign = hmacsha256(AppKey, [AppId]+[timestamp]+[randNum])
token = base64(sv+[sign]+[AppId]+[0]+[randNum]+[timestamp]+[From])
Example (pseudocode):
AppId = "31yOb7ulVXoBLYcRbmFesMu8"
AppKey = "dpFhBlov5zOLBqYJXimg6udabM9g30FDJNgt2g"
from = "zax-A37658F19E24"
timestamp = 1686023607
randValue = 156542
sign = hmacsha256("dpFhBlov5zOLBqYJXimg6udabM9g30FDJNgt2g", "31yOb7ulVXoBLYcRbmFesMu8+1686023607+156542")
// sign: "6a85345348c66c64c1f69765bb5f9de4305f4d12f4fc5a9c2550e25750d810e2"
token = base64("sv+6a85345348c66c64c1f69765bb5f9de4305f4d12f4fc5a9c2550e25750d810e2+31yOb7ulVXoBLYcRbmFesMu8+0+156542+1686023607+zax-A37658F19E24")
// token: "c3YrNmE4NTM0NTM0OGM2NmM2NGMxZjY5NzY1YmI1ZjlkZTQzMDVmNGQxMmY0ZmM1YTljMjU1MGUyNTc1MGQ4MTBlMiszMXlPYjd1bFZYb0JMWWNSYm1GZXNNdTgrMCsxNTY1NDIrMTY4NjAyMzYwNyt6YXgtQTM3NjU4RjE5RTI0"
2. Send a request
Before sending a request, set the Authorization value in the Header to the token obtained as mentioned above
appendix
Golang Example
package main
import (
"crypto/hmac"
"crypto/rand"
"crypto/sha256"
"encoding/base64"
"encoding/hex"
"fmt"
"log"
"math/big"
"net/http"
"time"
)
func HmacSha256(key string, data string) string {
mac := hmac.New(sha256.New, []byte(key))
mac.Write([]byte(data))
return hex.EncodeToString(mac.Sum(nil))
}
func randNumber(min int64, max int64) int64 {
a := min
b := max - min
n, err := rand.Int(rand.Reader, big.NewInt(b))
if err != nil {
return time.Now().UnixNano()%b + a
}
return n.Int64() + a
}
type Token struct {
Type string // 类型
Sign string // 签名
AppId string //
Reserve int64 // 保留
Timestamp int64 // 时间戳(单位秒)
From string // 请求者
RandNum int64 // 随机数
appKey string //
}
func NewToken(appId, appKey string, from string) *Token {
t := &Token{
Type: "sv",
Sign: "",
AppId: appId,
Reserve: 0,
Timestamp: time.Now().Unix(),
From: from,
RandNum: randNumber(100000, 999999),
appKey: appKey,
}
return t
}
func (t *Token) sign() {
data := fmt.Sprintf("%v+%v+%v", t.AppId, t.Timestamp, t.RandNum)
t.Sign = HmacSha256(t.appKey, data)
}
func (t *Token) String() string {
t.sign()
data := fmt.Sprintf("%v+%v+%v+%v+%v+%v+%v", t.Type, t.Sign, t.AppId, t.Reserve, t.RandNum, t.Timestamp, t.From)
return base64.RawURLEncoding.EncodeToString([]byte(data))
}
func (t *Token) RealTimeString() string {
t.Timestamp = time.Now().Unix()
t.RandNum = randNumber(100000, 999999)
return t.String()
}
const (
AppId = "31yOb7ulVXoBLYcRbmFesMu8"
AppKey = "dpFhBlov5zOLBqYJXimg6udabM9g30FDJNgt2g"
from = "zax-A37658F19E24"
)
// SendRequest 发送请求
func SendRequest(request *http.Request) (*http.Response, error) {
request.Header.Set("Authorization", NewToken(AppId, AppKey, from).RealTimeString())
return http.DefaultClient.Do(request)
}
func main() {
token := NewToken(AppId, AppKey, from)
log.Println(token.RealTimeString())
request, _ := http.NewRequest(http.MethodPost, "https://domain/api", nil)
response, _ := SendRequest(request)
_ = response
}
java
package token_demo;
import java.nio.charset.StandardCharsets;
import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException;
import java.util.Base64;
import java.util.Random;
import javax.crypto.Mac;
import javax.crypto.SecretKey;
import javax.crypto.spec.SecretKeySpec;
public class Token {
String appId;
String appKey;
String type; // 类型
String sign; // 签名
int reserve; // 保留
long timestamp; // 时间戳(单位秒)
String from; // 请求者
int randNum;// 随机数
public Token(String appId, String appKey, String from) {
this.appId = appId;
this.from = from;
this.appKey = appKey;
this.type = "sv";
this.reserve = 0;
this.timestamp = System.currentTimeMillis() / 1000;
this.randNum = new Random().nextInt(999999 - 100000) + 100000;
}
private void Sign() throws InvalidKeyException, NoSuchAlgorithmException {
String data = String.format("%s+%d+%d", this.appId, this.timestamp, this.randNum);
this.sign = this.HmacSha256(this.appKey, data);
}
public String String() throws InvalidKeyException, NoSuchAlgorithmException {
this.Sign();
String data = String.format("%s+%s+%s+%d+%d+%d+%s", this.type, this.sign, this.appId, this.reserve,
this.randNum, this.timestamp, this.from);
return Base64.getUrlEncoder().encodeToString(data.getBytes());
}
public String RealTimeString() throws InvalidKeyException, NoSuchAlgorithmException {
this.timestamp = System.currentTimeMillis() / 1000;
this.randNum = new Random().nextInt(999999 - 100000) + 100000;
return this.String();
}
String HmacSha256(String key, String data) throws NoSuchAlgorithmException, InvalidKeyException {
SecretKey secretKey = new SecretKeySpec(key.getBytes(StandardCharsets.UTF_8), "HmacSHA256");
Mac mac = Mac.getInstance(secretKey.getAlgorithm());
mac.init(secretKey);
byte[] out = mac.doFinal(data.getBytes(StandardCharsets.UTF_8));
return bytesToHex(out);
}
private String bytesToHex(byte[] hash) {
StringBuilder hexString = new StringBuilder();
for (byte b : hash) {
String hex = Integer.toHexString(0xff & b);
if (hex.length() == 1) {
hexString.append('0');
}
hexString.append(hex);
}
return hexString.toString();
}
public static void main(String[] args) throws NoSuchAlgorithmException, InvalidKeyException {
String AppId = "31yOb7ulVXoBLYcRbmFesMu8";
String AppKey = "dpFhBlov5zOLBqYJXimg6udabM9g30FDJNgt2g";
String from = "zax-A37658F19E24";
Token t = new Token(AppId, AppKey, from);
for (int i = 0; i < 10; i++) {
System.out.println(t.RealTimeString());
}
}
}
Problems encountered when integrating WebApp pages in Iframe
1. Cross domain pages in iframes cannot write cookies, resulting in the failure of interfaces that rely on cookies to pass tokens; At present, all interfaces in the webapp already carry tokens in their URLs. reference resources
Accessing the microphone in an iframe requires adding an allow attribute to the iframe tag, otherwise the page in the iframe cannot be accessed.
Grammar:
Permissions-Policy:<directive> <allowlist>allow='Permissions-Policy'
<iframe src="<https://example.com>" allow="microphone https://example.com;"></iframe>
Reference Documents
Deprecating Permissions in Cross-Origin Iframes
How to solve cross domain problems after deploying servers online

Format of login free redirect address
Jump using username and password:
http://192.168.88.11:9780/client/webapps/safeProduction/#/login?&user=admin&password=123456&device=PU_55AA00
https://www.dunhun.cn/client/app/#/login?&user=test&password=123&device=PU_22060310device
The parameter is used to indicate the jump to the corresponding device details interface. If not filled in, it will jump to the homepage after logging in.
Jump using token:
Benefit: Passwords will not be leaked during redirection.
http://192.168.88.11:9780/client/webapps/safeProduction/#/login?&token=2CC73DBF37BF358F809FD435DDC1EB8C&device=PU_55AA00
The third-party platform does not call the login interface and obtains the token through the appid and key.
Refer to the interface instructions for third-party platform docking e
@besovideo/webrtc-player
https://www.npmjs.com/package/@besovideo/webrtc-player