# 自定义授权

## 功能路径

`我的直播` --> `频道设置`-->`观看条件设置`-->`自定义授权`

## 功能介绍

打开直播观看页时，直播系统会调用客户系统的验证接口，客户自定义验证逻辑，验证通过后才能打开保利威视直播观看页，并且接口返回的观众账号具有唯一性，即同一个账号不能在两个地方同时登录，较早登录的账号会被踢出。

![](/files/IrmqKlH6TRueyzOaUkp9)

1、Secretkey：用于校验签名的生成

2、自定义URL: 用于自定义授权验证的API接口

## 自定义授权流程详解

1、在自定义URL处填写用户的授权验证API接口，需要完整的不带参数的url地址（不能是localhost等本地服务器地址，且不能带 ?号），如：<http://myWebsite.com/auth>

2、直播系统会将id（直播的频道）、ts（当前时间的毫秒级时间戳）、sign（用于校验的签名）、url（回调的url地址）等参数提交给用户自定义的API接口，用户需要对字符串secretkey + id + secretkey + ts进行MD5加密后与sign参数的值做比较判断是否合法。

3、通过校验和自定义验证逻辑后，客户系统将userid（学员唯一标识，仅支持英文大小写、数字和下划线）、nickname（昵称）、avatar（头像）、actor（用户头衔名称，非必须）、actorFColor（用户头衔字体颜色，非必须，请使用CSS Hex值带#号）、actorBgColor（用户头衔背景颜色，非必须，请使用CSS Hex值带#号）、vid（回放的视频id）、ts（当前时间的毫秒级时间戳）、sign（校验签名）等参数提交到回调的url接口。

4、直播系统会对签名做校验后判断是否允许学员观看.校验通过后将进入直播观看页，聊天区域将显示观众的昵称和头像。一次成功请求后，该链接将失效。

**流程图如下**

![](/files/QNtKV4FywERPMbtiao5H)

## 提交的参数描述

| 参数名  | 说明                                                              |
| ---- | --------------------------------------------------------------- |
| id   | 直播的频道号 ，如: 10000                                                |
| ts   | 当前时间的毫秒数长整型。如: 1466648001977                                    |
| sign | 用于校验的签名，生成的规则：对字符串secretkey + id + secretkey + ts 进行MD5加密生成的字符串 |
| url  | 用于回调url地址，用户在通过校验并处理后会跳到这个url                                   |
| vid  | 回放视频id,非必须字段,如通过回放地址链接登入观看页,则会将该参数提交给用户自定义地址。如：e07738ddd6       |

**直播系统会将上面的参数提交给用户自定义的api接口,用户需要对字符串secretkey + id +secretkey + ts进行MD5加密后与sign参数的值做比较判断是否合法。**

## 回调的url的参数描述

| 参数名          | 说明                                                                                                                                                                                                   |
| ------------ | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| userid       | 用户id，重复id时先登录的观众会被踢出直播间【仅支持英文大小写、数字和下划线，长度最大64位字符，超出64位的部分将被截取不做记录】                                                                                                                                  |
| nickname     | 用户的昵称进行base64加密的字符串后再进行urlencode，注：昵称编码前不能包含&、<、"、'等字符，不得含有xss脚本，否则会被转义处理                                                                                                                            |
| marqueeName  | 自定义跑马灯字段进行base64加密的字符串后再进行urlencode，该字段会通过【[URL自定义跑马灯](https://git.polyv.net/help-center/document-center/-/blob/master/live/api/player/marquee_url_instruction/README.md)】中code参数回调                  |
| avator       | 用户的头像,完整的图片地址字符串                                                                                                                                                                                     |
| actor        | 用户头衔名称,非必须字段                                                                                                                                                                                         |
| actorFColor  | 用户头衔自定义字体颜色,非必须字段                                                                                                                                                                                    |
| actorBgColor | 用户头衔自定义背景色,非必须字段                                                                                                                                                                                     |
| vid          | <p>回放视频id,非必须字段。 如：e07738ddd6。<br>该值可使用接口【<a href="https://git.polyv.net/help-center/document-center/-/blob/master/live/api/channel/playback/get_playback_list/README.md">查询视频库列表</a>】返回的videoId</p> |
| ts           | 当前的系统时间的毫秒数,长整型。如: 1466648001977                                                                                                                                                                     |
| sign         | 于校验的签名,生成的规则:对字符串secretkey + id + secretkey + ts +secretkey + userid进行MD5加密生成的字符串                                                                                                                    |

**通过第一步的校验后用户接口需要将上面相关的参数提交到回调的url接口，直播系统会对签名做校验后判断是否允许用户观看. 一次成功请求后,该链接将失效。**

## 代码示例（Java）

注：LiveSignUtil属于[直播SDK](https://git.polyv.net/help-center/document-center/-/blob/master/live/java/README.md)，如不使用直播SDK可使用以下第二点中的“MD5签名方法”。

```java
@Slf4j
@Controller
@RequestMapping(value = "/polyv")
public class PolyvController {
    
    private static final String SECRET = "******";
    
    @GetMapping("custom")
    public String custom(String id, Long ts, String sign, String url) throws UnsupportedEncodingException {
        Assert.assertNotBlack(id);
        Assert.assertNotNull(ts);
        Assert.assertNotBlack(sign);
        Assert.assertNotBlack(url);
        long timeMillis = System.currentTimeMillis();
        long diffTime = Math.abs(timeMillis - ts);
        //1、时间戳判断
        if (diffTime > 5 * 60 * 1000) {
            log.error("时间戳验证错误");
            return "";
        }
        String signText = SECRET + id + SECRET + ts;
        try {
            signText = LiveSignUtil.md5Hex(signText);
        } catch (NoSuchAlgorithmException e) {
            e.printStackTrace();
        } catch (UnsupportedEncodingException e) {
            e.printStackTrace();
        }
        if (signText == null || !signText.equals(sign)) {
            return "";
        }
        String viewerId = "sadboy";
        String nickname = URLEncoder.encode(new BASE64Encoder().encode("保利威".getBytes(StandardCharsets.UTF_8)), "GBK");
        String marqueeName = URLEncoder.encode(new BASE64Encoder().encode("跑马灯".getBytes(StandardCharsets.UTF_8)),
                "GBK");
        String avatar = "http://live.polyv.net/assets/images/avatars/9avatar.jpg"; //学员的头像
        String mySign = SECRET + id + SECRET + timeMillis + SECRET + viewerId;
        try {
            mySign = LiveSignUtil.md5Hex(mySign);
        } catch (NoSuchAlgorithmException e) {
            log.error("签名异常", e);
        }
        url += "?userid=" + viewerId + "&nickname=" + nickname + "&marqueeName=" + marqueeName + "&avatar=" + avatar +
                "&ts=" + timeMillis + "&sign=" + mySign;
        return "redirect:" + url;
    }
    
}
```

## 代码示例（PHP）

```java
<?php
$secretkey = "jlw42byyJ6"; //后台secretKey，在自定义授权地址设置页面
$id        = $_GET["id"]; //直播的频道id
$ts        = $_GET["ts"]; //当前时间
$sign      = $_GET["sign"]; //用于检验的签名
$url       = $_GET["url"]; //回调的url
$md5       = md5($secretkey . $id . $secretkey . $ts); //若md5字符串与sign不符合，则不做任何处理
if (!($sign == $md5)) {
    return;
}
$userid       = "eciyhturt8"; //学员唯一标识
$nickname     = urlencode(base64_encode("保利威")); //学员的昵称
$marqueeName     = urlencode(base64_encode("polyv")); //自定义跑马灯内容
$avatar       = "http://live.polyv.net/assets/images/avatars/9avatar.jpg"; //学员的头像
$callbackTs   = time() * 1000; //当前的系统时间
$callbackSign = md5($secretkey . $id . $secretkey . $callbackTs . $secretkey . $userid); //用于检验的签名
$callbackUrl  = $url . "?userid=" . $userid . "&nickname=" . $nickname . "&marqueeName=" . $marqueeName. "&avatar=" . $avatar . "&ts=" . $callbackTs . "&sign=" . $callbackSign; //新的直播页面url
//打开新的直播页面url
echo "<script language='javascript' type='text/javascript'>location.href='" . $callbackUrl . "'</script>"
?>

```

## 展示效果

<http://live.polyv.cn/watch/104400>

## 注意事项

1、要保证自定义验证接口返回的userid的唯一性，当多个观众使用同一个userid进入观看页时，较早登录的观众会被后面登录的观众踢出，观看页会提示 "帐号在另外的地方登录,您将被退出观看。如下图：

![](/files/wLa4dDIh94f1WAnn3Iu1)

2、学员的昵称进行base64加密后再进行urlencode加密，否则可能会造成观看页昵称显示乱码现象。

3、学员的昵称不能为空，否则保利威系统会取默认昵称 xxx观众/数字


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://polyv.gitbook.io/document/docs/live/api/web/watch-condition/customauth_2.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
