# 自定义授权

## 功能路径

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

## 功能介绍

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

![](https://6941759-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FmV4PIbrO79lRJl9HCeLg%2Fuploads%2Fgit-blob-38a93bebda2cfe39eafa70d90e6a00816c832716%2Fcustom_auth_view.png?alt=media)

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

**流程图如下**

![](https://6941759-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FmV4PIbrO79lRJl9HCeLg%2Fuploads%2Fgit-blob-f781655b17ada7c003b317b0f1b0f83d9f51a787%2Fcustom_auth_flow_chat.png?alt=media)

## 提交的参数描述

| 参数名  | 说明                                                              |
| ---- | --------------------------------------------------------------- |
| 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进入观看页时，较早登录的观众会被后面登录的观众踢出，观看页会提示 "帐号在另外的地方登录,您将被退出观看。如下图：

![](https://6941759-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FmV4PIbrO79lRJl9HCeLg%2Fuploads%2Fgit-blob-dce41251aa61c6465538770046e569eb7e39d4bb%2Fexit_view_notice.png?alt=media)

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

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