保利威文档中心

幫助中心

外部授權

更新時間:2026-08-07 10:11:41

功能介紹

1、當需要觀眾登入機構的使用者系統,驗證通過後才能進入直播觀看頁時,可使用外部授權。驗證觀眾是否可觀看由機構實作,驗證通過後開啟的觀看頁面由保利威實作。

2、機構後台針對通過驗證的觀眾,開啟直播觀看頁時 URL 需帶上指定的參數,經過直播系統驗證請求合法後,直播系統會呼叫客戶在後台設定的自訂授權驗證介面,進行介面授權驗證,兩次驗證通過,才能進入直播觀看頁,並且介面回傳的觀眾帳號具有唯一性,即同一個帳號不能在兩個地方同時登入,較早登入的帳號會被踢出。

1、Secretkey:用於校驗簽章的產生。

2、自訂 URL:用於外部授權驗證的 API 介面。

3、跳轉位址:觀眾直接存取 Polyv 觀看頁,會跳轉到該位址;若跳轉位址為空,則顯示預設提示頁。

展示效果

https://demo.ipolyv.cn/chenwb/open.php

外部授權流程詳解

1、在自訂 URL 處填寫使用者的授權驗證 API 介面,需要完整的不帶參數的 url 位址(不能是 localhost 等本地伺服器位址,且不能帶 ? 號),如:http://myWebsite.com/auth

2、在請求保利威視直播觀看頁時需帶上 userid(使用者 ID,僅支援英文大小寫、數字和底線)、ts(目前時間的毫秒級時間戳記)和 sign(用於校驗的簽章,產生規則是 secretkey + userid + secretkey + ts 進行 MD5 加密),如 https://live.polyv.cn/watch/125527?userid=6b3a43&ts=1498547407000&sign=dd9dc9e42ad7c0204398e925a4ee0f46

3、直播系統會對字串 secretkey+userid+secretkey+ts 進行 MD5 加密後與使用者提交的 sign 參數的值做比較判斷是否合法。一次成功請求後,該連結將失效(sign 只能成功使用一次)。如果合法,直播系統將呼叫使用者的 api 介面,並把 userid(使用者 ID)、ts(目前時間的毫秒級時間戳記)、channelId(頻道號)和 token(用於校驗的簽章)四個參數透過 GET 請求傳給使用者。如果不合法,則給出錯誤提示。

4、使用者 API 介面取得 userid、ts 和 token 參數後,進行簽章驗證。如果驗證通過,則將學員相關資訊和可選的觀看權限 watchAccess(詳參「使用者系統回傳觀眾資訊回應參數描述」)回傳給直播系統。

5、直播系統接收使用者 API 介面回傳的資料,如果驗證成功,則進入到保利威視直播觀看頁,聊天區將顯示學員的暱稱和頭像。watchAccess 為 trial 時,直播系統將結合頻道的外部授權試看配置判斷是否進入試看;如果驗證失敗,則給出錯誤提示。

互動圖如下

參數描述

請求觀看頁所帶參數

使用者將以下的參數提交給直播的觀看頁,(例如:https://live.polyv.cn/watch/125527?userid=test&ts=1565948760108&sign=b0b6eb22b6fa5e5684873052c27a6cef)

直播系統會對 sign 進行驗證,判斷是否合法,一次成功請求後,該連結將失效(sign 只能成功使用一次)

參數名 必選 說明
userid true 觀眾 id,重複 id 時先登入的觀眾會被踢出直播間,【僅支援英文大小寫、數字和底線,長度最大 64 位字元,超出 64 位的部分將被截取不做記錄
ts true 13 位毫秒級時間戳記
sign true 使用者校驗的簽章(字母小寫),加密規則:secretkey + userid + secretkey + ts
vid false 回放影片 id,如需回放某個回放影片,則需要傳該參數,如:e07738ddd6
該值可使用介面【查詢影片庫列表】回傳的 videoId

觀看頁請求觀眾資訊介面參數

觀看頁請求使用者在後台設定的自訂 URL 取得觀眾資訊,以下為請求所帶的參數

參數名 必填 參數說明
userid true 觀眾 id,重複 id 時先登入的觀眾會被踢出直播間,【僅支援英文大小寫、數字和底線,長度最大 64 位字元】
channelId true 頻道號
ts true 目前時間的 13 位毫秒級時間戳記
token true 用於校驗的簽章,產生的規則:對字串 secretkey + userid + secretkey + ts 進行 MD5 加密產生的字串(字母小寫)

使用者系統回傳觀眾資訊回應參數描述

字段 類型 必填 字段說明
status int true 請求結果,1 表示成功,0 表示失敗
userid string true 觀眾 id,【僅支援英文大小寫、數字和底線,長度最大 64 位字元】
nickname string true 觀眾暱稱
marqueeName string false 自訂跑馬燈字段,該字段會透過【URL 自訂跑馬燈】中 code 參數回調
avatar string true 觀眾頭像位址,頭像尺寸 200*200,體積不超過 30KB。
actor string false 觀眾頭銜
actorFColor string false 觀眾頭銜字體顏色,非必須,請使用 CSS Hex 值並且帶 # 號
actorBgColor string false 觀眾頭銜背景顏色,非必須,請使用 CSS Hex 值帶 # 號
param4 string false 統計觀眾觀看日誌的自訂參數
param5 string false 統計觀眾觀看日誌的自訂參數
errorUrl string false 請求失敗時觀看頁跳轉的位址(會帶上 channelId 和 userid)
userTags string 陣列 false 觀眾業務標籤,用於問卷定向彈出匹配(僅外部授權場景生效)。支援傳入一個或多個標籤;客戶建立問卷配置匹配條件後,攜帶任一匹配標籤的觀眾進入直播間將彈出對應問卷,未攜帶或為空時不彈出
watchAccess string false 外部授權觀看權限。allow:正式觀看;trial:結合頻道的外部授權試看配置判斷是否進入試看。未傳、空值或其他值按 allow 處理。該字段僅在 status 為 1 時生效

回應範例

成功範例

{
    "status":1,
    "userid":"2qwerty",
    "nickname":"testNick",
    "actor":"paul",
    "actorFColor":"#123123",
    "actorBgColor":"#FFFFFF",
    "param4":"param4test",
    "userTags":["vip","registered"],
    "watchAccess":"trial",
    "avatar":"http://live.polyv.net/assets/images/avatars/9avatar.jpg"
}

異常範例

{
    "status":0,
    "errorUrl":"http://test.com"
}

外部授權試看

頻道可透過修改頻道資訊介面配置外部授權試看開關、試看時長、有效截止時間和試看結束跳轉位址,對應字段如下:

字段 說明
extTrialWatchEnabled 外部授權試看開關,Y:開啟,N:關閉
extTrialWatchTime 試看時長,單位為分鐘
extTrialWatchEndTime 試看有效截止時間,不傳表示永久有效
extTrialRedirectUrl 試看耗盡後的跳轉位址

以上字段屬於頻道配置,不需要在客戶外部授權介面的回應中回傳。客戶外部授權介面只需透過 watchAccess 表達目前觀眾的觀看權限:

watchAccess 處理方式
allow 正式觀看,不受外部授權試看時長限制
trial 結合頻道外部授權試看配置判斷是否進入試看
未傳、空值或其他值 按 allow 處理,保持原有外部授權邏輯

status 的優先級高於 watchAccess:status 不為 1 時仍按外部授權失敗處理;只有 status 為 1 時 watchAccess 才會生效。watchAccess 為 trial 但頻道未開啟外部授權試看、試看配置已過期或配置不完整時,不進入試看限制。

付費或業務完成後的狀態刷新

客戶完成付費、報名、資料補充或認證後,應使該觀眾再次請求客戶外部授權介面時回傳 watchAccess=allow,例如:

{
    "status":1,
    "userid":"2qwerty",
    "nickname":"testNick",
    "watchAccess":"allow",
    "avatar":"http://live.polyv.net/assets/images/avatars/9avatar.jpg"
}

同一瀏覽器工作階段內,目前直播場次已經存在試看記錄時,觀眾返回原觀看頁並重新取得頻道觀看資訊,直播系統會再次請求客戶外部授權介面。該重新整理不要求試看時長已經耗盡,也不要求頻道目前仍在直播中;客戶回傳 allow 後,觀眾切換為正式觀看。回傳 trial 或介面呼叫失敗時,繼續保持目前試看狀態。

客戶外部授權介面應支援重複、冪等呼叫,並根據 userid 查詢最新業務狀態。短時間內的重複重新整理可能被合併,客戶不應依賴每次觀看頁請求都產生一次外部授權回調。同一瀏覽器工作階段仍然有效時,不需要重新產生帶 ts、sign 的觀看位址;工作階段失效、跨瀏覽器或更換裝置時,仍需重新執行完整外部授權流程。

程式碼範例(JAVA)

註:LiveSignUtil 屬於直播 SDK,如不使用直播 SDK 可使用以下第三點中的「MD5 簽名方法」。

1、使用者系統產生觀看連結

    public static void main(String[] args) {
        //TODO 设置频道号
        String channelId = "2275495";
        
        //TODO 设置externalKey
        String secret = "";
        
        // TODO 设置直播观看页地址
        //      如果使用定制域名,可在“查询频道信息”接口中获取到频道的观看地址 watchUrl
        //      https://help.polyv.net/index.html#/live/api/v4/channel/operate/get_channel_detail
        String url = "https://live.polyv.cn/watch/"+channelId;
        
        // TODO 根据实际情况设置userid
        String userid = "sadboy";
        
        String ts = String.valueOf(System.currentTimeMillis());
        String signText = secret+ userid +secret+ts;
        try {
            String sign = LiveSignUtil.md5Hex(signText);
            url += "?userid="+userid+"&ts="+ts+"&sign="+sign;
            log.info(url);
        } catch (NoSuchAlgorithmException e) {
            e.printStackTrace();
        } catch (UnsupportedEncodingException e) {
            e.printStackTrace();
        }
    }

2、使用者伺服器校驗 polyv 直播系統回調

@Slf4j
@Controller
@RequestMapping(value = "/polyv")
public class PolyvController {
    
//TODO 修改secretKey
private static final String secret = "******";
    
    @GetMapping("external")
    @ResponseBody
    public Map<String, Object> external(String channelId,String userid, Long ts, String token) {
        Assert.assertNotBlack(userid);
        Assert.assertNotBlack(token);
        Assert.assertNotNull(ts);
        HashMap<String, Object> map = new HashMap<>();
        long timeMillis = System.currentTimeMillis();
        long diffTime = Math.abs(timeMillis - ts);
        //1、时间戳判断
        if (diffTime > 5 * 60 * 1000) {
            log.error("时间戳验证错误");
            map.put("status", 0);
            //抛出异常时,如果设置errorUrl,则会跳转到 errorUrl ,如果未返回 errorUrl,则先查询 外部授权参数
            // externalRedirectUri,externalRedirectUri不为空则跳转externalRedirectUri地址,externalRedirectUri为空则跳转保利威默认页面
            map.put("errorUrl", "https://www.polyv.net");
            return map;
        }
        //2、签名判断
        String signText = secret + userid + secret + ts;
        String sign = null;
        try {
            sign = LiveSignUtil.md5Hex(signText);
        } catch (NoSuchAlgorithmException e) {
            e.printStackTrace();
        } catch (UnsupportedEncodingException e) {
            e.printStackTrace();
        }
        if (sign == null || !sign.equals(token)) {
            log.error("签名验证错误");
            map.put("status", 0);
            //抛出异常时,如果设置errorUrl,则会跳转到 errorUrl ,如果未返回 errorUrl,则先查询 外部授权参数
            // externalRedirectUri,externalRedirectUri不为空则跳转externalRedirectUri地址,externalRedirectUri为空则跳转保利威默认页面
            map.put("errorUrl", "https://www.polyv.net");
            return map;
        }
        //TODO 业务逻辑处理,后续需根据具体需求进行数据库操作
        //3、正常返回
        map.put("status", 1);
        map.put("userid", userid);
        map.put("nickname", "保利威测试用户");
        map.put("marqueeName", "保利威测试跑马灯");
        map.put("actor", "学生");
        map.put("actorFColor", "#2469f3");
        map.put("actorBgColor", null);
        map.put("param4", null);
        map.put("param5", null);
        // 未完成付费或业务流程时返回trial,完成后返回allow
        map.put("watchAccess", "trial");
        map.put("avatar", "https://help.polyv.net/favicon.ico");
        return map;
    }
    
    
}

3、MD5 簽名方法

    /**
     * 对字符串做MD5加密,返回加密后的字符串。
     * @param text 待加密的字符串。
     * @return 加密后的字符串。
     * @throws NoSuchAlgorithmException 签名异常
     *  @throws UnsupportedEncodingException 编码异常
     */
    public static String md5Hex(String text) throws NoSuchAlgorithmException, UnsupportedEncodingException {
         
            MessageDigest messageDigest = MessageDigest.getInstance("MD5");
            byte[] inputByteArray = text.getBytes(LiveConstant.UTF8);
            messageDigest.update(inputByteArray);
            byte[] resultByteArray = messageDigest.digest();
            return byteArrayToHex(resultByteArray).toLowerCase();
         
    }
    
    /**
     * 将字节数组换成成16进制的字符串
     * @param byteArray 字节
     * @return 字符串
     */
    public static String byteArrayToHex(byte[] byteArray) {
        // 初始化一个字符数组用来存放每个16进制字符
        char[] hexDigits = {'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F'};
        // new一个字符数组,这个就是用来组成结果字符串的(一个byte是八位二进制,也就是2位十六进制字符(2的8次方等于16的2次方))
        char[] resultCharArray = new char[byteArray.length * 2];
        // 遍历字节数组,通过位运算(位运算效率高),转换成字符放到字符数组中去
        int index = 0;
        for (byte b : byteArray) {
            resultCharArray[index++] = hexDigits[b >>> 4 & 0xf];
            resultCharArray[index++] = hexDigits[b & 0xf];
        }
        // 字符数组组合成字符串返回
        return new String(resultCharArray);
    }

程式碼範例(PHP)

<?php
header("Content-type:application/json;charset=UTF-8"); //媒体格式类型为JSON数据格式
$secretkey = "aDrOt0Cpy8";
$userid    = isset($_GET["userid"]) ? $_GET["userid"] : "";
$ts        = isset($_GET["ts"]) ? $_GET["ts"] : "";
$channelId = isset($_GET["channelId"]) ? $_GET["channelId"] : "";
$token     = isset($_GET["token"]) ? $_GET["token"] : "";
$sign      = md5($secretkey . $userid . $secretkey . $ts);

//用户进行授权验证,返回对应的数据(json格式)
if ($sign == $token) {
    //验证正确
    $array1 = array(
        "status"   => 1, //返回状态
        "userid"   => $userid, //学员唯一标识
        "nickname" => "保利威", //学员昵称
        "marqueeName" => "polyv", //自定义跑马灯字段
        "avatar"   => "http://live.polyv.net/assets/images/avatars/9avatar.jpg", //学员头像
        "actor"   => "VIP",  // 学员头衔,可以不传递
        "actorFColor"   => "#5C96E5",  // 学员头衔字体颜色,可以不传递
        "actorBgColor"   => "#FFFFFF",  // 学员头衔背景颜色,可以不传递
        "watchAccess" => "trial" // 未完成付费或业务流程时返回trial,完成后返回allow
    );
    $json1 = json_encode($array1);
    echo $json1;
} else {
    //验证错误
    $array0 = array(
        "status"   => 0,
        "errorUrl" => "http://xxx.xx.xxxx/error.html", //验证错误跳转的自定义页面
    );
    $json0 = json_encode($array0);
    echo $json0;
}

注意事項

1、要保證自訂驗證介面回傳的 userid 的唯一性,當多個觀眾使用同一個 userid 進入觀看頁時,較早登入的觀眾會被後面登入的觀眾踢出,觀看頁會提示「帳號在另外的地方登入,您將被退出觀看。如下圖:

2、自訂驗證介面需要填寫完整的 URL 位址,且不能是 localhost 等本地伺服器位址。

3、自訂驗證介面回傳給直播系統的資料格式是 json 格式。

4、同時傳入了 nickname 和 marqueeName,在觀看日誌中,marqueeName 將作為使用者暱稱的統計字段。

5、watchAccess 僅在 status 為 1 時生效。客戶介面應支援重複、冪等呼叫,並根據 userid 回傳最新的觀看權限。

錯誤提示

1、user not found:請求自訂驗證介面錯誤,或者介面回傳的格式不對。

2、invalid sign:簽名錯誤,sign 的產生規則是 secretkey+userid+secretkey+ts 進行 MD5 加密。

3、sign expired:簽名過期,每一個 sign 只能使用一次,使用後需重新產生。

联系客服,在线咨询