互动视频
  • iOS
  • Android : Java
  • macOS
  • Windows
  • Linux
  • Web
  • 小程序
  • Electron
  • 概述
  • 限制说明
  • SDK 下载
  • 快速开始
  • 常用功能
  • 推拉流进阶
  • 视频进阶
  • 音频进阶
  • 其他功能
  • 废弃接口
  • API 文档
  • 常见错误码
  • 常见问题
  • AI教育
  • KTV 合唱
  • 视频直播
  • 视频通话
  • 游戏直播
  • 直播答题
  • 娃娃机
  • 文档中心
  • 互动视频
  • 快速开始
  • 用户权限控制

使用 Token 鉴权

更新时间:2022-03-24 11:38

1 功能简介

鉴权是指验证用户是否拥有访问系统的权限,来避免因权限控制缺失或操作不当引发的安全风险问题,ZEGO 通过 Token(包括基础鉴权 Token 和权限认证 Token) 对用户进行鉴权。

基础鉴权 Token 指的是开发者在登录房间前必须通过 SetToken 接口将 Token 传给 SDK,来验证用户的合法性。

权限认证 Token 指的是为了进一步提高安全性开放了房间 ID 和推流 ID 这两个权限位,可以验证登录房间的 ID 和推流 ID。

房间 ID 和推流 ID 权限位的一般使用场景如下:

  • 房间有普通房间和会员房间的区别,需要控制非会员用户登录会员房间。
  • 语聊房中,需要控制推流用户和麦上用户的一致,防止“幽灵麦”现象,即在房间里听到了非麦上用户声音的情况。
  • 狼人杀等发言游戏,需要防止应用被黑客破解之后,黑客可以使用其他用户 ID 登录同一房间,获取到游戏进行的信息进行作弊,影响正常用户的游戏体验。

2 前提条件

  • 基础鉴权 Token 默认开通,权限认证 Token(即房间 ID 和推流 ID 权限位)请联系 ZEGO 技术支持开通。
  • 已在项目中集成 ZEGO LiveRoom SDK(6.9.0 及以上版本),实现基本的实时音视频功能。

3 实现流程

使用 Token 鉴权时,需要开发者先生成 Token,ZEGO 服务端对带着 Token 的用户进行校验。

以使用 Token 判断用户是否能登录房间为例介绍使用流程,如下图:

token_uml

  1. 开发者客户端发起申请 Token 的请求。
  2. 在开发者的服务端上生成 Token,并返回给开发者客户端。
  3. 开发者客户端携带申请到的 Token 和 roomID 信息,通过 SetToken 接口传入 SDK。
  4. ZEGO SDK 会自动将 Token 发送到 ZEGO 服务端进行校验。
  5. ZEGO 服务端会将校验结果返回给 ZEGO SDK。
  6. ZEGO SDK 再将校验的结果直接返回给开发者客户端,没有权限的客户端将登录失败。

4 使用步骤

本节将详细介绍开发者如何生成 Token、如何使用 Token 和 Token 过期时的处理方式。

4.1 获取 AppId 和 ServerSecret

生成 Token 需要开发者项目的唯一标识 AppId 和密钥 ServerSecret,请参考 控制台 - 项目管理 中的 “项目信息”获取。

4.2 生成 Token

4.2.1 服务端生成 Token(推荐)

开发者获得项目的 AppID 和 ServerSecret 信息后,根据实际业务需求,即可在自己的服务端生成 Token。开发者客户端向开发者服务端发送申请 Token 请求,由开发者服务端生成 Token 后返回给到对应客户端。

ZEGO 在 GitHub/Gitee 提供了一个开源的 zego_server_assistant 插件,支持使用 Go、C++、Java、Objective-C、Python、PHP、.NET、Node.js 语言,在开发者的服务端或客户端部署生成 Token。

zego_server_assistant 插件中提供了生成基础鉴权 Token 和生成权限认证 Token 的示例代码,两者的适用场景如下,开发者可按需选择:

  • 基础鉴权 Token:用于业务的简单权限验证的场景,此时 “payload” 字段可传空。
  • 权限认证 Token:为了进一步提高安全性,开放房间 ID 和推流 ID 这两个权限位,可以验证登录房间的 ID 和推流 ID,此时 “payload” 字段需要按照规则生成,可参考下表的“权限认证 Token”示例代码。权限位校验规则如下:
    • 只校验登录权限:登录时校验权限,推流时不校验权限。
    • 校验推流权限:推流时校验权限,登录时不校验权限。
    • 同时校验登录和推流权限:登录和推流时均校验权限。
  • 为保证安全性,强烈推荐您使用服务端生成 Token,否则会存在 ServerSecret 被窃取的风险。
  • 请使用 zego_server_assistant 中的 “token04” 来生成 Token。

zego_server_assistant 插件中用于服务端生成 Token 的各语言参考信息如下:

语言 支持版本 关键函数 代码库地址 示例代码地址
基础鉴权 Token 权限认证 Token
Go
Go 1.14.15 或以上版本
GenerateToken04
C++
C++ 11 或以上版本
GenerateToken04
Java
Java 1.8 或以上版本
generateToken04
Python
Python 3.6.8 或以上版本
generate_token04
PHP
PHP 5.6 或以上版本
generateToken04
.NET
.NET Framework 3.5 或以上版本
GenerateToken04
Node.js
Node.js 8 或以上版本
generateToken04

以 Go 语言为例,开发者可参考以下步骤使用 zego_server_assistant 生成 Token:

  1. 使用命令 go get github.com/zegoim/zego_server_assistant 获取依赖包。
  2. 在您的代码中,通过 import "github.com/zegoim/zego_server_assistant/token/go/src/token04" 引入插件。
  3. 调用插件提供的 GenerateToken04 方法生成 Token。

可通过如下三种方式生成 Token。

  • 方式 1:基础鉴权 Token
    生成基础鉴权 Token 示例代码如下:
package main

import (
    "fmt"
    "github.com/zegoim/zego_server_assistant/token/go/src/token04"
)

/*
基础鉴权token生成示例代码
*/

func main() {
    var appId uint32 = 1                               // Zego派发的数字ID, 各个开发者的唯一标识
    userId := "demo"                                   // 用户 ID
    serverSecret := "fa94dd0f974cf2e293728a1234567890" // 在获取 token 时进行 AES 加密的密钥
    var effectiveTimeInSeconds int64 = 3600            // token 的有效时长,单位:秒
    var payload string = ""                            // token业务认证扩展,基础鉴权token此处填空

    //生成token
    token, err := token04.GenerateToken04(appId, userId, serverSecret, effectiveTimeInSeconds, payload)
    if err != nil {
    fmt.Println(err)
    return
    }
    fmt.Println(token)
}
  • 方式 2:权限认证 Token
    生成权限认证 Token 的示例代码如下:

生成权限认证 Token 时必须传入 “RoomId”。

package main

import (
    "encoding/json"
    "fmt"
    "github.com/zegoim/zego_server_assistant/token/go/src/token04"
)

/*
权限认证token生成示例代码
*/

//token业务扩展:权限认证属性
type RtcRoomPayLoad struct {
    RoomId       string      `json:"room_id"`        //房间 id(必填);用于对接口的房间 id 进行强验证
    Privilege    map[int]int `json:"privilege"`      //权限位开关列表;用于对接口的操作权限进行强验证
    StreamIdList []string    `json:"stream_id_list"` //流列表;用于对接口的流 id 进行强验证;允许为空,如果为空,则不对流 id 验证
}

func main() {
    var appId uint32 = 1                               // Zego派发的数字ID, 各个开发者的唯一标识
    roomId := "demo"                                   // 房间 ID
    userId := "demo"                                   // 用户 ID
    serverSecret := "fa94dd0f974cf2e293728a526b028271" // 在获取 token 时进行 AES 加密的密钥
    var effectiveTimeInSeconds int64 = 3600            // token 的有效时长,单位:秒

    //请参考 github.com/zegoim/zego_server_assistant/token/go/src/token04/token04.go 定义
    ////权限位定义
    //const (
    //    PrivilegeKeyLogin   = 1 // 登录权限位认证
    //    PrivilegeKeyPublish = 2 // 推流权限位认证
    //)

    ////权限开关定义
    //const (
    //    PrivilegeEnable     = 1 // 有权限
    //    PrivilegeDisable    = 0 // 无权限
    //)

    //业务权限认证配置,可以配置多个权限位
    privilege := make(map[int]int)
    privilege[token04.PrivilegeKeyLogin] = token04.PrivilegeEnable    // 有房间登录权限
    privilege[token04.PrivilegeKeyPublish] = token04.PrivilegeDisable // 无推流权限

    //token业务扩展配置
    payloadData := &RtcRoomPayLoad{
    RoomId:       roomId,
    Privilege:    privilege,
    StreamIdList: nil,
    }

    payload, err := json.Marshal(payloadData)
    if err != nil {
    fmt.Println(err)
    return
    }

    //生成token
    token, err := token04.GenerateToken04(appId, userId, serverSecret, effectiveTimeInSeconds, string(payload))
    if err != nil {
    fmt.Println(err)
    return
}
    fmt.Println(token)
}

运行生成 Token 的 Java 源码时,如果出现 “java.security.InvalidKeyException:illegal Key Size” 异常提示,请参考 相关常见问题文档 解决。

  • 方式 3: 控制台获取 Token
    Token 临时获取方式:为方便开发者调试,ZEGO 控制台 提供生成临时 Token 的功能,开发者可直接获取临时 Token 来使用,详情请参考 控制台 - 开发辅助。但是在开发者自己的线上环境中,一定要通过自己的服务端生成 Token。

4.2.2 客户端生成 Token(不推荐)

若您在开发过程中还无法通过服务端下发 Token 时,可以先使用客户端代码生成 Token,待服务端开发完后,再完成对接。

  • App 上线时,切勿在客户端生成 Token,否则您的 ServerSecret 将暴露在风险中。
  • 为保证安全性,强烈推荐您使用服务端生成 Token,否则会存在 ServerSecret 被窃取的风险。

zego_server_assistant 插件中用于客户端生成 Token 的各语言参考信息如下:

语言 支持版本 关键函数 具体地址
C++
C++ 11 或以上版本
GenerateToken04
Java
Java 1.8 或以上版本
generateToken04
Objective-C
-
GenerateToken04

4.3 设置 Token

用户携带获取到的 Token 和 roomID 信息,在登录房间和推流之前通过 setToken 接口将 Token 传入给 SDK。

zegoLiveRoom.setToken(token, roomID);

如果开发者需要在登录房间后修改权限位,也可以调用 setToken 接口更新 Token,更新后会影响下一次登录某些房间和推某些流的权限,之前已经成功的房间登录和推流不受影响。

getToken(roomID, new ITokenCompletionCallback() {
    @Override
    public void onTokenCompletion(String token) {
        zegoLiveRoom.setToken(token, roomID);
    }
});

4.4 Token 过期机制

在 Token 过期前 30 秒,SDK 会通过 onTokenWillExpired 回调发出通知。

收到该回调后,开发者需要从自己的服务端获取新的有效 Token,并再次调用 SDK 提供的 setToken 接口更新 Token。若未处理,不同版本对 Token 过期的处理机制有所不同:

  • 若您接入的是 gb6c19ce606 及以上版本的 ZEGO LiveRoom SDK,此时如果未更新 Token,则在 Token 过期时:
    • 已登录的用户不会被踢出房间。
    • 当前已成功推送的流不受影响,但是会影响用户的下一次推流操作。
  • 若您接入的是 6.5.0 及以上版本的 ZEGO LiveRoom SDK:
    • 可以联系 ZEGO 技术支持额外配置 Token 过期管理机制,此时如果未更新 Token,则当 Token 过期时:
      • 已登录的用户会被踢出房间,且无法再登录房间。
      • 当前已成功推送的流会被停止,也无法进行下一次推流。
    • 若未联系 ZEGO 技术支持额外配置 Token 过期管理机制,此时如果未更新 Token:
      • 已登录的用户不会被踢出房间。
      • 当前已成功推送的流不受影响,但是会影响用户的下一次推流操作。
  • 如未开启推流权限校验,则不受影响。
  • 若开启了登录权限校验,用户登录房间时必须主动传入新的 Token。
//...
@Override
void onTokenWillExpired(String roomID, int remainTimeInSecond) {
    final String finalRoomId = roomID;
    getToken(roomID, new ITokenCompletionCallback() {
        @Override
        public void onTokenCompletion(String token) {
            zegoLiveRoom.setToken(token, finalRoomId);
        }
    });
}

5 API 参考

方法 描述
setToken 设置 Token
onTokenWillExpired Token 即将过期回调
本篇目录