Pano开发者中心
  • 开发者中心
  • 下载中心

›规则说明

新手入门

  • 简介
  • 名词解释
  • 创建第一个应用

规则说明

  • Channel ID命名规则
  • 权限控制
  • 计费说明
  • 频道最大时长说明
  • 每月一万分钟免费说明
  • 布局参数说明
  • 水印

场景方案

    教育行业

    • 1vN互动小班课
    • 互动直播大班课

快速接入

  • 简介
  • 音视频

    • Windows (C++)
    • iOS (Objective-C)
    • Android (Java)
    • Web
    • Electron
    • Flutter
    • React Native
    • Unity

    白板

    • Windows (C++)
    • iOS (Objective-C)
    • Android (Java)
    • Web
    • Electron
    • Flutter
    • React Native

高级功能(RTC)

  • 简介
  • 屏幕共享
  • 分组讨论
  • 状态回调
  • 设备诊断
  • 音量指示
  • 控制声音
  • 声卡操作
  • 混音/伴音
  • 混响
  • 耳返
  • 变声
  • 美颜
  • 音视频数据回调
  • 音视频外部采集
  • 收发多路视频
  • 多窗口渲染
  • 性能检测
  • 截图
  • 反馈

高级功能(RTS)

  • 简介
  • 白板

    • Windows (C++)
    • iOS (Objective-C)
    • Android (Java)
    • Web
    • Flutter

    标注

    • 视频标注
    • 共享标注
    • 外部标注

    消息

    • 消息服务

    远程控制

    • 远程控制

操作实践

  • 切换大小屏

RESTful API

  • 基本格式
  • 生成Token
  • 频道管理
  • 云端录制
  • CDN推流
  • 文档转码
  • 消息服务
  • 服务端消息通知

SDK API

  • SDK接口说明
  • Windows (C++)
  • macOS/iOS (Objective-C)
  • Android (Java)
  • Web SDK (IE专用版)
  • Web SDK

    • 浏览器兼容性
    • RtcEngine
    • GroupManager
    • RtcWhiteboard
    • RtsService
    • RtcMessage
    • Annotation
    • Constants

更新记录

  • 简介
  • Windows
  • macOS
  • iOS
  • Android
  • Electron
  • Flutter
  • React Native
  • Unity
  • Web(全功能SDK)
  • Web(RTS SDK)
  • Web(IE专用音视频SDK)

帮助

  • FAQ
  • 更多帮助

权限控制

Pano提供了完善的权限控制功能,确保安全访问。

App Server到Pano Cloud

App Server到Pano Cloud的访问为 RESTful API over HTTPS 。为了安全性考虑,对Pano Cloud的RESTful API调用建议经由用户自己的服务器,即由App Server发起。比如,一些会控操作,申请Token等。

将一些请求经由App Server发起主要是考虑到保护用户的App Secret,App Secret相当于用户在Pano里的特殊密码,这些信息必须得到妥善保管,客户端不应直接使用。

Http请求头信息示例:

POST /<endpoint>
Host: api.pano.video
Content-Type: application/json
Authorization: PanoSign <PanoSign>
Cache-Control: no-cache

为了进一步增加安全性,RESTful请求时并不直接带上App Secret,而是带上 PanoSign,请将上面示例中的<PanoSign>替换为真实的PanoSign(<>表示变量,实际的PanoSign里不需要)。

PanoSign格式

PanoSign由三部分组成,用.拼接在一起,格式为<appId>.<timestamp>.<signature>,各字段含义如下:

  • <appId> - 你的App ID,请登录 控制台,在应用管理模块查看你的App ID
  • <timestamp> - 当前UTC时间戳(精确到秒)
  • <signature> - 签名,由App ID、当前UTC时间戳、App Secret计算获得,详细算法如下:
signature = base64(HmacSHA256(appId+timestamp,appSecret))
  • 首先,将appId和当前UTC时间戳(精确到秒)拼接作为签名内容,appSecret作为签名key。加入当前UTC时间戳的目的是限制生成的signature只在很短的时间内有效,所以请注意设置正确的时间(建议同步NTP)
  • 然后,通过HmacSHA256哈希算法以App Secret作为秘钥计算得到一个hash值
  • 最后,将hash值经过base64编码

signature 计算示例和 PanoSign 生成示例:

Java
Go
Python2
Python3
PHP
import javax.crypto.Mac;
import javax.crypto.spec.SecretKeySpec;
import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException;
import java.io.UnsupportedEncodingException;
import java.util.Base64;

public class MyClass {
public static String signature(String appId, long timestamp, String appSecret)
throws NoSuchAlgorithmException, InvalidKeyException, UnsupportedEncodingException
{
String message = appId + timestamp;
Mac hmacSha256 = Mac.getInstance("HmacSHA256");
SecretKeySpec secretKey = new SecretKeySpec(appSecret.getBytes("UTF-8"), "HmacSHA256");
hmacSha256.init(secretKey);
byte[] bytes = hmacSha256.doFinal(message.getBytes("UTF-8"));
return Base64.getEncoder().encodeToString(bytes);
}

public static String generatePanoSign(String appId, String appSecret)
throws NoSuchAlgorithmException, InvalidKeyException, UnsupportedEncodingException
{
long timestamp = System.currentTimeMillis() / 1000L;
String sign = appId + "." + timestamp + "." + signature(appId, timestamp, appSecret);
return sign;
}
}
import (
"fmt"
"time"
"crypto/hmac"
"crypto/sha256"
"encoding/base64"
)

func signature(appId string, timestamp int64, appSecret string) string {
mac := hmac.New(sha256.New, []byte(appSecret))
mac.Write([]byte(fmt.Sprintf("%s%d", appId, timestamp)))
return base64.StdEncoding.EncodeToString(mac.Sum(nil))
}

func generatePanoSign(appId string, appSecret string) string {
current := time.Now().Unix()
return fmt.Sprintf("%s.%d.%s", appId, current, signature(appId, current, appSecret))
}
import time
import hmac
import base64
from hashlib import sha256


def genSignature(appId, timestamp, appSecret):
message = appId + timestamp
signature = base64.b64encode(hmac.new(appSecret, message, digestmod=sha256).digest())
return signature


def generatePanoSign(appId, appSecret):
timestamp = str(int(time.time()))
sign = appId + "." + timestamp + "." + genSignature(appId, timestamp, appSecret)
return sign
import time
import hmac
import base64
from hashlib import sha256


def genSignature(appId, timestamp, appSecret):
message = appId + timestamp
message_bytes = bytes(message, 'utf-8')
secret_bytes = bytes(appSecret, 'utf-8')
signature = base64.b64encode(hmac.new(secret_bytes, message_bytes, digestmod=sha256).digest())
return signature.decode('utf-8')


def generatePanoSign(appId, appSecret):
timestamp = str(int(time.time()))
sign = appId + "." + timestamp + "." + genSignature(appId, timestamp, appSecret)
return sign
function getPanoSign($appId, $appSecret){
$timestamp = time();
// https://www.php.net/manual/zh/function.hash-hmac.php
// raw_output 设置为 true 输出原始二进制数据
$signature = base64_encode(hash_hmac("sha256", $appId . $timestamp, $appSecret, true));
$panoSign = $appId . "." . $timestamp . "." . $signature;
return $panoSign;
}

下面是Http请求头的一个示例:

POST /auth/token
Host: api.pano.video
Content-Type: application/json
Authorization: PanoSign e7d3fb36131345f0a922b27c8c5c2019.1570498816.c31f97d3797de14f9d8e2c17f3ab165f070f9dc6547aadb5e9706763dc29a0c8
Tracking-Id: ef9b2acc8e1f4d598090eb6d9cbe8596

下面是生成的一个PanoSign示例:

e7d3fb36131345f0a922b27c8c5c2019.1570498816.c31f97d3797de14f9d8e2c17f3ab165f070f9dc6547aadb5e9706763dc29a0c8

校验PanoSign

Pano服务器会校验PanoSign,并对timestamp进行检查。

为了缩短和Pano服务器之间的时间误差,App Server端用于生成时间戳的机器必须要跟NTP保持同步。

为了保障安全,原则上要求每次请求都生成新的PanoSign。

SDK到Pano Cloud

SDK与Pano Cloud的所有交互都需要token,因此所有交互之前都需要有一个合法有效的token,token可以在开始通话前生成,也可以提前生成。一般的流程如下:

  1. App Client调用App Server的接口申请token,这一步的安全保证由客户自行实现,客户采用自己的鉴权方式和调用方式来保证安全
  2. App Server调用Pano Cloud的接口申请token,这一步的安全保证参考上一节的内容
  3. Pano Cloud返回token给App Server,App Server返回给App Client
  4. App Client将token传给Pano SDK
  5. Pano SDK使用token与Pano Cloud交互,Pano Cloud通过校验token合法性来保证SDK的合法性

申请token需要appId、userId、channelId、duration、privileges等信息,从申请token的参数可以知道,token是和appId、channelId、userId绑定的,如果是不同的appId、不同的channelId、不同的userId,需要申请不同的token。

获取token的RESTful API细节请参考这里。同时,我们也提供了AppServer的示例代码供参考和调试使用。

token有效期由参数duration定义,默认为24小时,失效后需要重新申请一个有效的token。

参数privileges是Pano为客户提供的一个可选的权限机制,具体用法参考下一节。

Token Privileges

Pano SDK默认是具备发送音频、发送视频等各种能力的,你如果需要限制用户某些能力,你可以在App Client里控制End User的权限,譬如在用户界面上进行控制,不给没有权限的用户提供UI入口。

除了控制UI入口,开发者还可以选择给不同权限的用户申请具有不同权限的token。这样,Pano会根据token里的权限信息来帮助实现更完善的权限控制。

token privileges的使用流程一般如下:

  1. 申请token时,针对不同的用户,给不同的privileges参数
  2. Pano Cloud在生成token时增加权限属性
  3. SDK使用token与Pano Cloud交互,Pano Cloud校验token权限
  4. 如果权限不足,则拒绝相关操作

privileges定义了如下权限:发送音频、发送视频、进行白板互动、发送Screen Share等,在生成Token时有一个参数privileges用于传入权限信息。

privileges参数的值是16bits的数字,每个bit代表一种权限:

 0                   1 
 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|         privileges            |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+

各个bit的定义如下(bit 0为高位):

  • bit 0 - 是否启用权限控制, bit 0 = 1时后面的bits才有效
  • bit 1 - 是否可以发送音频
  • bit 2 - 是否可以发送视频
  • bit 3 - 是否可以进行白板互动
  • bit 4 - 是否可以发送Screen Share
  • bit 5 ~ bit 15 - reserved as 0

用法举例:

  • privileges = 0,不启用权限
  • privileges = 49152,二进制:1100 0000 0000 0000,十六进制即0xC000,表示可以发送音频,其他权限没有
  • privileges = 63488,二进制:1111 1000 0000 0000,十六进制即0xF800,表示可以发送音频、发送视频、进行白板互动、发送Screen Share

从上述权限定义可以发现,Pano并不限制接收方的权限,也就是说,所有人都有这些权限:接收音频、订阅视频、接收白板、订阅Screen Share等。

token privileges是一个可选的权限机制,可以使用,也可以不使用。

Last updated on 2021/12/13
← Channel ID命名规则计费说明 →
  • App Server到Pano Cloud
    • PanoSign格式
    • 校验PanoSign
  • SDK到Pano Cloud
  • Token Privileges
浙ICP备20002645号 ©2019-2022 Pano拍乐云