使用 Token 鉴权
鉴权是指在用户访问你的系统前,对用户权限进行校验,声网用 Token 对用户鉴权。Token 也称为动态密钥,是在加入频道时用于校验用户权限的一组字符串。当 App 用户使用声网服务,如加入 RTC 频道时传入 Token,声网服务端会根据 Token 中的信息校验用户的权限。
你可以根据你的使用场景,通过下列任意一种方式来设置 Token 的权限:
- 统一设置权限:统一设置加入频道并发流的权限,适用于绝大多数场景,详见实现 Token 鉴权。
- 精细控制发布不同流的权限:开通连麦鉴权功能,分别设置在频道内发布音频流、视频流、数据流的权限,适用于对安全要求较高的场景,详见使用连麦鉴权。
本文仅适用于 AccessToken2,如果你使用的是 AccessToken,请先参考 AccessToken 升级指南将 AccessToken 升级至 AccessToken2。
下图展示声网使用 Token 对用户鉴权的流程:
前提条件
开始前,请确保你的项目满足如下条件:
实现 Token 鉴权
本节以生成 Token 并加入频道为例,介绍如何使用 Token 进行鉴权。为确保你的业务的安全性,声网推荐你对每一个加入频道的客户端都进行鉴权。
生成 Token
声网在 GitHub 上提供一个开源的 Token 生成器代码仓库 AgoraDynamicKey,支持使用 C++、Java、Golang 等多种语言来在你自己的服务器上生成 Token。
以下列出的语言均基于 HMAC-SHA256 算法生成 Token。
以 C++ 为例,你可以通过 privilege_expiration_in_seconds
来统一设置所有权限的过期时间。
示例代码如下:
- C++
- Golang
- Java
- Node.js
- PHP
- Python
- Python3
#include <cstdlib>
#include <iostream>
#include "../src/RtcTokenBuilder2.h"
using namespace agora::tools;
int main(int argc, char const *argv[]) {
(void)argc;
(void)argv;
// 获取环境变量 AGORA_APP_ID 的值。请确保你将该变量设为你在声网控制台获取的 App ID
const char *env_app_id = getenv("AGORA_APP_ID");
std::string app_id = env_app_id ? env_app_id : "";
// 获取环境变量 AGORA_APP_CERTIFICATE 的值。请确保你将该变量设为你在声网控制台获取的 App 证书
const char *env_app_certificate = getenv("AGORA_APP_CERTIFICATE");
std::string app_certificate = env_app_certificate ? env_app_certificate : "";
// 将 channelName 替换为需要加入的频道名
std::string channel_name = "channelName";
// 填入你实际的用户 ID
uint32_t uid = 2882341273
// Token 的有效时间,单位秒
uint32_t token_expiration_in_seconds = 3600;
// 所有的权限的有效时间,单位秒,声网建议你将该参数和 Token 的有效时间设为一致
uint32_t privilege_expiration_in_seconds = 3600;
std::string result;
std::cout << "App Id:" << app_id << std::endl;
std::cout << "App Certificate:" << app_certificate << std::endl;
if (app_id == "" || app_certificate == "") {
std::cout << "Need to set environment variable AGORA_APP_ID and "
"AGORA_APP_CERTIFICATE"
<< std::endl;
return -1;
}
// 生成 Token
result = RtcTokenBuilder2::BuildTokenWithUid(
app_id, app_certificate, channel_name, uid, UserRole::kRolePublisher,
token_expiration_in_seconds, privilege_expiration_in_seconds);
std::cout << "Token With Int Uid:" << result << std::endl;
return 0;
}
package main
import (
"fmt"
"os"
rtctokenbuilder "github.com/AgoraIO/Tools/DynamicKey/AgoraDynamicKey/go/src/rtctokenbuilder2"
)
func main() {
// 获取环境变量 AGORA_APP_ID 的值。请确保你将该变量设为你在声网控制台获取的 App ID
appId := os.Getenv("AGORA_APP_ID")
// 获取环境变量 AGORA_APP_CERTIFICATE 的值。请确保你将该变量设为你在声网控制台获取的 App 证书
appCertificate := os.Getenv("AGORA_APP_CERTIFICATE")
// 将 channelName 替换为需要加入的频道名
channelName := "channelName"
// 填入你实际的用户 ID
uid := uint32(2882341273)
// Token 的有效时间,单位秒
tokenExpirationInSeconds := uint32(3600)
// 所有的权限的有效时间,单位秒,声网建议你将该参数和 Token 的有效时间设为一致
privilegeExpirationInSeconds := uint32(3600)
fmt.Println("App Id:", appId)
fmt.Println("App Certificate:", appCertificate)
if appId == "" || appCertificate == "" {
fmt.Println("Need to set environment variable AGORA_APP_ID and AGORA_APP_CERTIFICATE")
return
}
// 生成 Token
result, err := rtctokenbuilder.BuildTokenWithUid(appId, appCertificate, channelName, uid, rtctokenbuilder.RolePublisher, tokenExpirationInSeconds, privilegeExpirationInSeconds)
if err != nil {
fmt.Println(err)
} else {
fmt.Printf("Token with int uid: %s\n", result)
}
}
package io.agora.sample;
import io.agora.media.RtcTokenBuilder2;
import io.agora.media.RtcTokenBuilder2.Role;
public class RtcTokenBuilder2Sample {
// 获取环境变量 AGORA_APP_ID 的值。请确保你将该变量设为你在声网控制台获取的 App ID
static String appId = System.getenv("AGORA_APP_ID");
// 获取环境变量 AGORA_APP_CERTIFICATE 的值。请确保你将该变量设为你在声网控制台获取的 App 证书
static String appCertificate = System.getenv("AGORA_APP_CERTIFICATE");
// 将 channelName 替换为需要加入的频道名
static String channelName = "channelName";
// 填入你实际的用户 ID
static int uid = 2082341273;
// Token 的有效时间,单位秒
static int tokenExpirationInSeconds = 3600;
// 所有的权限的有效时间,单位秒,声网建议你将该参数和 Token 的有效时间设为一致
static int privilegeExpirationInSeconds = 3600;
public static void main(String[] args) {
System.out.printf("App Id: %s\n", appId);
System.out.printf("App Certificate: %s\n", appCertificate);
if (appId == null || appId.isEmpty() || appCertificate == null || appCertificate.isEmpty()) {
System.out.printf("Need to set environment variable AGORA_APP_ID and AGORA_APP_CERTIFICATE\n");
return;
}
// 生成 Token
RtcTokenBuilder2 token = new RtcTokenBuilder2();
String result = token.buildTokenWithUid(appId, appCertificate, channelName, uid, Role.ROLE_PUBLISHER, tokenExpirationInSeconds, privilegeExpirationInSeconds);
System.out.printf("Token with uid: %s\n", result);
}
}
const RtcTokenBuilder = require("../src/RtcTokenBuilder2").RtcTokenBuilder;
const RtcRole = require("../src/RtcTokenBuilder2").Role;
// 获取环境变量 AGORA_APP_ID 的值。请确保你将该变量设为你在声网控制台获取的 App ID
const appId = process.env.AGORA_APP_ID;
// 获取环境变量 AGORA_APP_CERTIFICATE 的值。请确保你将该变量设为你在声网控制台获取的 App 证书
const appCertificate = process.env.AGORA_APP_CERTIFICATE;
// 将 channelName 替换为需要加入的频道名
const channelName = "channelName";
// 填入你实际的用户 ID
const uid = 2882341273;
// 设为具有发流权限
const role = RtcRole.PUBLISHER;
// Token 的有效时间,单位秒
const tokenExpirationInSecond = 3600;
// 所有的权限的有效时间,单位秒,声网建议你将该参数和 Token 的有效时间设为一致
const privilegeExpirationInSecond = 3600;
console.log("App Id:", appId);
console.log("App Certificate:", appCertificate);
if (appId == undefined || appId == "" || appCertificate == undefined || appCertificate == "") {
console.log("Need to set environment variable AGORA_APP_ID and AGORA_APP_CERTIFICATE");
process.exit(1);
}
// 生成 Token
const tokenWithUid = RtcTokenBuilder.buildTokenWithUid(appId, appCertificate, channelName, uid, role, tokenExpirationInSecond, privilegeExpirationInSecond);
console.log("Token with int uid:", tokenWithUid);
<?php
include("../src/RtcTokenBuilder2.php");
// 获取环境变量 AGORA_APP_ID 的值。请确保你将该变量设为你在声网控制台获取的 App ID
$appId = getenv("AGORA_APP_ID");
// 获取环境变量 AGORA_APP_CERTIFICATE 的值。请确保你将该变量设为你在声网控制台获取的 App 证书
$appCertificate = getenv("AGORA_APP_CERTIFICATE");
// 将 channelName 替换为需要加入的频道名
$channelName = "channelName";
// 填入你实际的用户 ID
$uid = 2882341273;
// Token 的有效时间,单位秒
$tokenExpirationInSeconds = 3600;
// 所有的权限的有效时间,单位秒,声网建议你将该参数和 Token 的有效时间设为一致
$privilegeExpirationInSeconds = 3600;
echo "App Id: " . $appId . PHP_EOL;
echo "App Certificate: " . $appCertificate . PHP_EOL;
if ($appId == "" || $appCertificate == "") {
echo "Need to set environment variable AGORA_APP_ID and AGORA_APP_CERTIFICATE" . PHP_EOL;
exit;
}
// 生成 Token
$token = RtcTokenBuilder2::buildTokenWithUid($appId, $appCertificate, $channelName, $uid, RtcTokenBuilder2::ROLE_PUBLISHER, $tokenExpirationInSeconds, $privilegeExpirationInSeconds);
echo 'Token with int uid: ' . $token . PHP_EOL;
import os
import sys
sys.path.insert(0, os.path.abspath(os.path.join(os.path.dirname(__file__), '..')))
from src.RtcTokenBuilder2 import *
def main():
# 获取环境变量 AGORA_APP_ID 的值。请确保你将该变量设为你在声网控制台获取的 App ID
app_id = os.environ.get("AGORA_APP_ID")
# 获取环境变量 AGORA_APP_CERTIFICATE 的值。请确保你将该变量设为你在声网控制台获取的 App 证书
app_certificate = os.environ.get("AGORA_APP_CERTIFICATE")
# 将 channel_name 替换为需要加入的频道名
channel_name = "channel_name"
# 填入你实际的用户 ID
uid = 2882341273
# Token 的有效时间,单位秒
token_expiration_in_seconds = 3600
# 所有的权限的有效时间,单位秒,声网建议你将该参数和 Token 的有效时间设为一致
privilege_expiration_in_seconds = 3600
print("App Id: %s" % app_id)
print("App Certificate: %s" % app_certificate)
if not app_id or not app_certificate:
print("Need to set environment variable AGORA_APP_ID and AGORA_APP_CERTIFICATE")
return
# 生成 Token
token = RtcTokenBuilder.build_token_with_uid(app_id, app_certificate, channel_name, uid, Role_Publisher,
token_expiration_in_seconds, privilege_expiration_in_seconds)
print("Token with int uid: {}".format(token))
if __name__ == "__main__":
main()
import os
import sys
sys.path.insert(0, os.path.abspath(os.path.join(os.path.dirname(__file__), '..')))
from src.RtcTokenBuilder2 import *
def main():
# 获取环境变量 AGORA_APP_ID 的值。请确保你将该变量设为你在声网控制台获取的 App ID
app_id = os.environ.get("AGORA_APP_ID")
# 获取环境变量 AGORA_APP_CERTIFICATE 的值。请确保你将该变量设为你在声网控制台获取的 App 证书
app_certificate = os.environ.get("AGORA_APP_CERTIFICATE")
# 将 channel_name 替换为需要加入的频道名
channel_name = "channel_name"
# 填入你实际的用户 ID
uid = 2882341273
# Token 的有效时间,单位秒
token_expiration_in_seconds = 3600
# 所有的权限的有效时间,单位秒,声网建议你将该参数和 Token 的有效时间设为一致
privilege_expiration_in_seconds = 3600
print("App Id: %s" % app_id)
print("App Certificate: %s" % app_certificate)
if not app_id or not app_certificate:
print("Need to set environment variable AGORA_APP_ID and AGORA_APP_CERTIFICATE")
return
# 生成 Token
token = RtcTokenBuilder.build_token_with_uid(app_id, app_certificate, channel_name, uid, Role_Publisher,
token_expiration_in_seconds, privilege_expiration_in_seconds)
print("Token with int uid: {}".format(token))
if __name__ == "__main__":
main()
以上示例代码中使用的是 int
型的用户 ID 来生成 Token。如果你需要使用 string
型的用户 ID 来生成 Token,请前往 Token 生成器代码仓库查看对应语言的相关方法及示例代码。
使用 Token
本节介绍如何使用 Token 对客户端加入频道的用户进行鉴权。
使用获取到的 Token 和用户 ID、频道名等信息,通过 joinChannel
[2/2] 方法加入频道。
加入频道时使用的用户 ID 和频道名必须和生成 Token 时的用户 ID 和频道名一致。
// 频道名
String channelId = "xxx";
// 用户名
int uid = 0;
// 请求服务端生成 channelId 和 uid 对应的 token
String token = getToken();
// 设置频道媒体选项
ChannelMediaOptions option = new ChannelMediaOptions();
option.clientRoleType = Constants.CLIENT_ROLE_BROADCASTER;
// 加入频道
engine.joinChannel(token, channelId, 0, option);
Token 过期处理
使用 Token 加入频道后,在 Token 过期前 30 秒,SDK 会触发 onTokenPrivilegeWillExpire
回调。
Token 过期时,SDK 会触发 onRequestToken
回调。
当收到上述回调后,你需要重新在服务端生成新的 Token,然后通过下列任意一种方式来更新 Token:
单频道场景
-
(推荐)调用
renewToken
来传入新生成的 Token。 -
调用
updateChannelMediaOptions
更新 Token。 -
调用
leaveChannel
[2/2] 离开当前频道,然后在调用joinChannel
[2/2] 时传入新的 Token 重新加入频道。
多频道场景
如果你调用了 joinChannelEx
加入多个频道,需要调用 updateChannelMediaOptionsEx
方法来更新 Token。
示例代码
下列示例代码展示在收到 onTokenPrivilegeWillExpire
回调提示 Token 即将过期时,调用 renewToken
来更新 Token。
class RtcEngineEventHandlerImpl extends IRtcEngineEventHandler {
// Token 即将过期时回调
@Override
public void onTokenPrivilegeWillExpire(String token) {
super.onTokenPrivilegeWillExpire(token);
// 重新请求生成 Token
String token = getToken();
// 更新 Token
engine.renewToken(token);
}
}
拓展功能(可选)
本节介绍 Token 相关的拓展功能,包括如何生成通配 Token、如何使用连麦鉴权来精细控制发流权限。
生成通配 Token
如果用户需要频繁切换频道、或同时加入多个频道,声网提供将用户 ID 或频道名设为通配符的通配 Token。用户可以复用同一 Token 加入不同频道,既可减少频繁获取 Token 所造成的耗时,从而加快切换、加入频道的速度,同时也能减小你的 Token 服务器的压力,详见通配 Token。
使用连麦鉴权
声网支持精细控制频道内用户发布不同流的权限,可确保频道内的发流用户都经过授权,从而防止黑客利用业务漏洞或盗取 Token 进行直播间炸房等行为。
- 在设置前,请确保你已开启连麦鉴权功能。
- 如果你需要在频道内发流,请确保在加入频道前,已调用
setClientRole
方法将用户角色设为主播(BROADCASTER
),或是在调用joinChannel
[2/2] 加入频道时通过options
将clientRoleType
设为CLIENT_ROLE_BROADCASTER
。
声网提供 BuildTokenWithUidAndPrivilege
方法来设置下列权限的过期时间:
- 加入频道
- 频道内发布音频流
- 频道内发布视频流
- 频道内发布数据流
详细参数说明见 API 参考。
生成 Token
声网在 GitHub 上提供一个开源的 Token 生成器代码仓库 AgoraDynamicKey,支持使用 C++、Java、Golang 等多种语言来在你自己的服务器上生成 Token。在生成时,你可以通过不同参数分别设置发布不同流的权限。
以下列出的语言均基于 HMAC-SHA256 算法生成 Token。
以 C++ 为例,你可以通过 join_channel_privilege_expiration_in_seconds
、pub_audio_privilege_expiration_in_seconds
、pub_video_privilege_expiration_in_seconds
、pub_data_stream_privilege_expiration_in_seconds
参数来分别设置加入频道、发布音频流、视频流、数据流的有效时间。
示例代码如下:
- C++
- Golang
- Java
- Node.js
- PHP
- Python
- Python3
#include <cstdlib>
#include <iostream>
#include "../src/RtcTokenBuilder2.h"
using namespace agora::tools;
int main(int argc, char const *argv[]) {
(void)argc;
(void)argv;
// 获取环境变量 AGORA_APP_ID 的值。请确保你将该变量设为你在声网控制台获取的 App ID
const char *env_app_id = getenv("AGORA_APP_ID");
std::string app_id = env_app_id ? env_app_id : "";
// 获取环境变量 AGORA_APP_CERTIFICATE 的值。请确保你将该变量设为你在声网控制台获取的 App 证书
const char *env_app_certificate = getenv("AGORA_APP_CERTIFICATE");
std::string app_certificate = env_app_certificate ? env_app_certificate : "";
// 将 channelName 替换为需要加入的频道名
std::string channel_name = "channelName";
// 填入你实际的用户 ID
uint32_t uid = 2882341273;
// Token 的有效时长(秒)
uint32_t token_expiration_in_seconds = 3600;
// 加入频道权限的有效时长(秒),声网建议将其他权限的有效时间和该参数设为一致
uint32_t join_channel_privilege_expiration_in_seconds = 3600;
// 频道内发布音频流权限的有效时长(秒)
uint32_t pub_audio_privilege_expiration_in_seconds = 3600;
// 频道内发布视频流权限的有效时长(秒)
uint32_t pub_video_privilege_expiration_in_seconds = 3600;
// 频道内发布数据流权限的有效时长(秒)
uint32_t pub_data_stream_privilege_expiration_in_seconds = 3600;
std::string result;
std::cout << "App Id:" << app_id << std::endl;
std::cout << "App Certificate:" << app_certificate << std::endl;
if (app_id == "" || app_certificate == "") {
std::cout << "Need to set environment variable AGORA_APP_ID and "
"AGORA_APP_CERTIFICATE"
<< std::endl;
return -1;
}
// 生成 Token
result = RtcTokenBuilder2::BuildTokenWithUid(
app_id, app_certificate, channel_name, uid, token_expiration_in_seconds,
join_channel_privilege_expiration_in_seconds,
pub_audio_privilege_expiration_in_seconds,
pub_video_privilege_expiration_in_seconds,
pub_data_stream_privilege_expiration_in_seconds);
std::cout << "Token With Int Uid:" << result << std::endl;
return 0;
}
package main
import (
"fmt"
"os"
rtctokenbuilder "github.com/AgoraIO/Tools/DynamicKey/AgoraDynamicKey/go/src/rtctokenbuilder2"
)
func main() {
// 获取环境变量 AGORA_APP_ID 的值。请确保你将该变量设为你在声网控制台获取的 App ID
appId := os.Getenv("AGORA_APP_ID")
// 获取环境变量 AGORA_APP_CERTIFICATE 的值。请确保你将该变量设为你在声网控制台获取的 App 证书
appCertificate := os.Getenv("AGORA_APP_CERTIFICATE")
// 将 channelName 替换为需要加入的频道名
channelName := "channelName"
// 填入你实际的用户 ID
uid := uint32(2882341273)
// Token 的有效时间(秒),声网建议将其他权限的有效时间和该参数设为一致
tokenExpirationInSeconds := uint32(3600)
// 加入频道权限的有效时间(秒)
joinChannelPrivilegeExpireInSeconds := uint32(3600)
// 频道内发布音频流权限的有效时间(秒)
pubAudioPrivilegeExpireInSeconds := uint32(3600)
// 频道内发布视频流权限的有效时间(秒)
pubVideoPrivilegeExpireInSeconds := uint32(3600)
// 频道内发布数据流权限的有效时间(秒)
pubDataStreamPrivilegeExpireInSeconds := uint32(3600)
fmt.Println("App Id:", appId)
fmt.Println("App Certificate:", appCertificate)
if appId == "" || appCertificate == "" {
fmt.Println("Need to set environment variable AGORA_APP_ID and AGORA_APP_CERTIFICATE")
return
}
// 生成 Token
result, err := rtctokenbuilder.BuildTokenWithUidAndPrivilege(
appId,
appCertificate,
channelName,
uid,
tokenExpirationInSeconds,
joinChannelPrivilegeExpireInSeconds,
pubAudioPrivilegeExpireInSeconds,
pubVideoPrivilegeExpireInSeconds,
pubDataStreamPrivilegeExpireInSeconds,
)
if err != nil {
fmt.Println(err)
} else {
fmt.Printf("Token with int uid and privilege: %s\n", result)
}
}
package io.agora.sample;
import io.agora.media.RtcTokenBuilder2;
public class RtcTokenBuilder2Sample {
// 获取环境变量 AGORA_APP_ID 的值。请确保你将该变量设为你在声网控制台获取的 App ID
static String appId = System.getenv("AGORA_APP_ID");
// 获取环境变量 AGORA_APP_CERTIFICATE 的值。请确保你将该变量设为你在声网控制台获取的 App 证书
static String appCertificate = System.getenv("AGORA_APP_CERTIFICATE");
// 将 channelName 替换为需要加入的频道名
static String channelName = "channelName";
// 填入你实际的用户 ID
static int uid = 2082341273;
// Token 的有效时间(秒),声网建议将其他权限的有效时间和该参数设为一致
static int tokenExpirationInSeconds = 3600;
// 加入频道权限的有效时间(秒)
static int joinChannelPrivilegeExpireInSeconds = 3600;
// 频道内发布音频流权限的有效时间(秒)
static int pubAudioPrivilegeExpireInSeconds = 3600;
// 频道内发布视频流权限的有效时间(秒)
static int pubVideoPrivilegeExpireInSeconds = 3600;
// 频道内发布数据流权限的有效时间(秒)
static int pubDataStreamPrivilegeExpireInSeconds = 3600;
public static void main(String[] args) {
System.out.printf("App Id: %s\n", appId);
System.out.printf("App Certificate: %s\n", appCertificate);
if (appId == null || appId.isEmpty() || appCertificate == null || appCertificate.isEmpty()) {
System.out.printf("Need to set environment variable AGORA_APP_ID and AGORA_APP_CERTIFICATE\n");
return;
}
// 生成 Token
result = token.buildTokenWithUid(appId, appCertificate, channelName, uid, tokenExpirationInSeconds,
joinChannelPrivilegeExpireInSeconds, pubAudioPrivilegeExpireInSeconds,
pubVideoPrivilegeExpireInSeconds,
pubDataStreamPrivilegeExpireInSeconds);
System.out.printf("Token with uid and privilege: %s\n", result);
}
}
const RtcTokenBuilder = require("../src/RtcTokenBuilder2").RtcTokenBuilder;
// 获取环境变量 AGORA_APP_ID 的值。请确保你将该变量设为你在声网控制台获取的 App ID
const appId = process.env.AGORA_APP_ID;
// 获取环境变量 AGORA_APP_CERTIFICATE 的值。请确保你将该变量设为你在声网控制台获取的 App 证书
const appCertificate = process.env.AGORA_APP_CERTIFICATE;
// 将 channelName 替换为需要加入的频道名
const channelName = "channelName";
// 填入你实际的用户 ID
const uid = 2082341273;
// Token 的有效时间(秒),声网建议将其他权限的有效时间和该参数设为一致
const tokenExpirationInSecond = 3600;
// 加入频道权限的有效时间(秒)
const joinChannelPrivilegeExpireInSeconds = 3600;
// 频道内发布音频流权限的有效时间(秒)
const pubAudioPrivilegeExpireInSeconds = 3600;
// 频道内发布视频流权限的有效时间(秒)
const pubVideoPrivilegeExpireInSeconds = 3600;
// 频道内发布数据流权限的有效时间(秒)
const pubDataStreamPrivilegeExpireInSeconds = 3600;
console.log("App Id:", appId);
console.log("App Certificate:", appCertificate);
if (appId == undefined || appId == "" || appCertificate == undefined || appCertificate == "") {
console.log("Need to set environment variable AGORA_APP_ID and AGORA_APP_CERTIFICATE");
process.exit(1);
}
// 生成 Token
const tokenWithUidAndPrivilege = RtcTokenBuilder.buildTokenWithUidAndPrivilege(
appId,
appCertificate,
channelName,
uid,
tokenExpirationInSecond,
joinChannelPrivilegeExpireInSeconds,
pubAudioPrivilegeExpireInSeconds,
pubVideoPrivilegeExpireInSeconds,
pubDataStreamPrivilegeExpireInSeconds
);
console.log("Token with int uid and privilege:", tokenWithUidAndPrivilege);
<?php
include("../src/RtcTokenBuilder2.php");
// 获取环境变量 AGORA_APP_ID 的值。请确保你将该变量设为你在声网控制台获取的 App ID
$appId = getenv("AGORA_APP_ID");
// 获取环境变量 AGORA_APP_CERTIFICATE 的值。请确保你将该变量设为你在声网控制台获取的 App 证书
$appCertificate = getenv("AGORA_APP_CERTIFICATE");
// 将 channelName 替换为需要加入的频道名
$channelName = "channelName";
// 填入你实际的用户 ID
$uid = 2882341273;
// Token 的有效时间(秒),声网建议将其他权限的有效时间和该参数设为一致
$tokenExpirationInSeconds = 3600;
// 加入频道权限的有效时间(秒)
$joinChannelPrivilegeExpireInSeconds = 3600;
// 频道内发布音频流权限的有效时间(秒)
$pubAudioPrivilegeExpireInSeconds = 3600;
// 频道内发布视频流权限的有效时间(秒)
$pubVideoPrivilegeExpireInSeconds = 3600;
// 频道内发布数据流权限的有效时间(秒)
$pubDataStreamPrivilegeExpireInSeconds = 3600;
echo "App Id: " . $appId . PHP_EOL;
echo "App Certificate: " . $appCertificate . PHP_EOL;
if ($appId == "" || $appCertificate == "") {
echo "Need to set environment variable AGORA_APP_ID and AGORA_APP_CERTIFICATE" . PHP_EOL;
exit;
}
// 生成 Token
$token = RtcTokenBuilder2::buildTokenWithUidAndPrivilege($appId, $appCertificate, $channelName, $uid, $tokenExpirationInSeconds, $joinChannelPrivilegeExpireInSeconds, $pubAudioPrivilegeExpireInSeconds, $pubVideoPrivilegeExpireInSeconds, $pubDataStreamPrivilegeExpireInSeconds);
echo 'Token with int uid and privilege: ' . $token . PHP_EOL;
import os
import sys
sys.path.insert(0, os.path.abspath(os.path.join(os.path.dirname(__file__), '..')))
from src.RtcTokenBuilder2 import *
def main():
# 获取环境变量 AGORA_APP_ID 的值。请确保你将该变量设为你在声网控制台获取的 App ID
app_id = os.environ.get("AGORA_APP_ID")
# 获取环境变量 AGORA_APP_CERTIFICATE 的值。请确保你将该变量设为你在声网控制台获取的 App 证书
app_certificate = os.environ.get("AGORA_APP_CERTIFICATE")
# 将 channel_name 替换为需要加入的频道名
channel_name = "channel_name"
# 填入你实际的用户 ID
uid = 2882341273
# Token 的有效时间(秒),声网建议将其他权限的有效时间和该参数设为一致
token_expiration_in_seconds = 3600
# 加入频道权限的有效时间(秒)
join_channel_privilege_expiration_in_seconds = 3600
# 频道内发布音频流权限的有效时间(秒)
pub_audio_privilege_expiration_in_seconds = 3600
# 频道内发布视频流权限的有效时间(秒)
pub_video_privilege_expiration_in_seconds = 3600
# 频道内发布数据流权限的有效时间(秒)
pub_data_stream_privilege_expiration_in_seconds = 3600
print("App Id: %s" % app_id)
print("App Certificate: %s" % app_certificate)
if not app_id or not app_certificate:
print("Need to set environment variable AGORA_APP_ID and AGORA_APP_CERTIFICATE")
return
# 生成 Token
token = RtcTokenBuilder.build_token_with_uid_and_privilege(
app_id, app_certificate, channel_name, uid, token_expiration_in_seconds,
join_channel_privilege_expiration_in_seconds, pub_audio_privilege_expiration_in_seconds, pub_video_privilege_expiration_in_seconds, pub_data_stream_privilege_expiration_in_seconds)
print("Token with int uid and privilege: {}".format(token))
if __name__ == "__main__":
main()
import os
import sys
sys.path.insert(0, os.path.abspath(os.path.join(os.path.dirname(__file__), '..')))
from src.RtcTokenBuilder2 import *
def main():
# 获取环境变量 AGORA_APP_ID 的值。请确保你将该变量设为你在声网控制台获取的 App ID
app_id = os.environ.get("AGORA_APP_ID")
# 获取环境变量 AGORA_APP_CERTIFICATE 的值。请确保你将该变量设为你在声网控制台获取的 App 证书
app_certificate = os.environ.get("AGORA_APP_CERTIFICATE")
# 将 channel_name 替换为需要加入的频道名
channel_name = "channel_name"
# 填入你实际的用户 ID
uid = 2882341273
# Token 的有效时间(秒),声网建议将其他权限的有效时间和该参数设为一致
token_expiration_in_seconds = 3600
# 加入频道权限的有效时间(秒)
join_channel_privilege_expiration_in_seconds = 3600
# 频道内发布音频流权限的有效时间(秒)
pub_audio_privilege_expiration_in_seconds = 3600
# 频道内发布视频流权限的有效时间(秒)
pub_video_privilege_expiration_in_seconds = 3600
# 频道内发布数据流权限的有效时间(秒)
pub_data_stream_privilege_expiration_in_seconds = 3600
print("App Id: %s" % app_id)
print("App Certificate: %s" % app_certificate)
if not app_id or not app_certificate:
print("Need to set environment variable AGORA_APP_ID and AGORA_APP_CERTIFICATE")
return
# 生成 Token
token = RtcTokenBuilder.build_token_with_uid_and_privilege(
app_id, app_certificate, channel_name, uid, token_expiration_in_seconds,
join_channel_privilege_expiration_in_seconds, pub_audio_privilege_expiration_in_seconds, pub_video_privilege_expiration_in_seconds, pub_data_stream_privilege_expiration_in_seconds)
print("Token with int uid and privilege: {}".format(token))
if __name__ == "__main__":
main()
以上此例代码中使用的是 int
型的用户 ID 来生成 Token。如果你需要使用 string
型的用户 ID 来生成 Token,请前往 Token 生成器代码仓库查看对应语言的相关方法及示例代码。
使用 Token
请参考使用 Token 来使用可精细控制发流权限的 Token。
部署与调试
本节介绍如何在你的本地来快速部署一个 Token 生成器,部署成功之后你可以用生成的 Token 调试你的项目。
方式一:通过 Docker 部署 Token 生成器
参考以下步骤在本地部署一个基于 Docker 的 Token 生成器并申请 Token:
在开始前,请确保你已安装 Docker。
-
打开终端,运行下列命令来启动 Token 生成器。将
[YOUR_APP_ID]
和[YOUR_APP_CERTIFICATE]
替换为你在声网控制台获取的 App ID 和 App 证书。Shelldocker run -d -it -p 8080:8080 -e APP_ID=[YOUR_APP_ID] -e APP_CERTIFICATE=[YOUR_APP_CERTIFICATE] --name agora-token-service agoracn/token:0.1.2023053011
-
运行下列命令来向你刚刚部署的 Token 生成器请求一个 Token:
Shellcurl --location 'http://localhost:8080/token/generate' \
--header 'Content-Type: application/json' \
--data '{
"channelName": "channel_name_test",
"uid": "12345678",
"tokenExpireTs": 3600,
"privilegeExpireTs": 3600,
"serviceRtc": {
"enable": true,
"role": 1
}
}'请求成功后,你的终端会返回生成的 Token。
方式二:本地手动部署 Token 生成器
以 Golang 语言为例,你可以参考如下步骤来在你本地搭建并运行一个 Token 生成器来生成 Token:
在开始前,请确保你的 Golang 版本是 1.14 或以上版本。
此示例仅用于演示,请勿用于生产环境中。
-
新建一个
token-server
文件夹,在该文件夹下创建一个server.go
文件,将使用 Golang 生成 Token 的示例代码贴入到该文件中,将其中的appID
和appCertificate
替换为你的 App ID 和 App 证书。 -
打开终端,进入到
token-server
文件路径下,运行如下命令行来为你的 Token 生成器创建go.mod
文件,该文件定义导入路径及依赖项:Go$ go mod init sampleServer
-
运行如下命令行安装依赖。你可以使用 Go 镜像进行加速,例如 https://goproxy.cn。
Go$ go get github.com/AgoraIO/Tools/DynamicKey/AgoraDynamicKey/go/src/rtctokenbuilder2
-
运行如下命令行启动 Token 生成器:
Go$ go run server.go
Token 生成器部署成功后,你的终端会返回根据你填入的 App ID 和 App 证书生成的 Token。
你也可以直接前往声网控制台获取临时 Token 来调试你的项目,详见获取临时 Token。
参考信息
对 SDK 的兼容性要求
AccessToken2 支持以下版本的声网 SDK(不包括客户端旁路推流功能):
- 对于 RTC 4.x SDK:Android、iOS、Windows、macOS、Electron、Unity、React Native、Unreal 平台的版本需大于等于 v4.0.0,HarmonyOS 平台需大于等于 4.4.0,Web 平台需大于等于 v4.8.0,Flutter 平台需大于等于 v6.0.0。
使用 AccessToken2 的 RTC SDK 可与使用 AccessToken 的 RTC SDK 互通。支持 AccessToken2 的 RTC SDK 也支持 AccessToken。
API 参考
以 Golang 语言为例,本节介绍生成 Token 的核心方法。
-
BuildTokenWithUid
:生成 Token,设置 Token 和所有权限的过期时间。 -
BuildTokenWithUidAndPrivilege
:生成 Token 并可精细控制发流权限。可设置 Token 的有效期以及加入频道权限、发布音频、视频、数据流权限的过期时间。
BuildTokenWithUid
生成 Token 并设置所有的权限过期时间。
func BuildTokenWithUid(appId string, appCertificate string, channelName string, uid uint32, role Role, tokenExpire uint32, privilegeExpire uint32)
参数
appId
:你在声网控制台创建项目时生成的 App ID。appCertificate
:你的项目的 App 证书。channelName
:频道名,长度在 64 个字节以内。uid
:待鉴权用户的用户 ID,32 位有符号整数,取值范围为 -231 - 1 到 231 - 1, 并保证唯一性。role
:用户权限,决定用户是否能在频道中发流。kRolePublisher
(1):(默认)用户有发流权限,即用户可在频道中发流。kRoleSubscriber
(2):用户有接收权限,即用户可在频道中接收,但不可发流。该参数仅在开启连麦鉴权后才生效。详情参考开启连麦鉴权。
tokenExpire
:Token 的有效时长(秒),最长有效期为 24 小时。privilegeExpire
:所有权限的有效时长(秒)。如设为 0(默认值),表示权限永不过期。
当 Token 过期但权限未过期时,用户仍在频道里并且可以发流,不会触发 SDK 中与 Token 相关的任何回调。但一旦和频道断开连接,用户将无法使用该 Token 加入同一频道。声网建议将 Token 的过期时间和权限过期时间设为一致。
BuildTokenWithUidAndPrivilege
生成 Token 并设置不同权限的过期时间。
func BuildTokenWithUidAndPrivilege(appId string, appCertificate string, channelName string, uid uint32,
tokenExpire uint32, joinChannelPrivilegeExpire uint32, pubAudioPrivilegeExpire uint32, pubVideoPrivilegeExpire uint32, pubDataStreamPrivilegeExpire uint32)
参数
appId
:你在声网控制台创建项目时生成的 App ID。appCertificate
:你的项目的 App 证书。channelName
:频道名,长度在 64 个字节以内。uid
:待鉴权用户的用户 ID,32 位有符号整数,取值范围为 -231 - 1 到 231 - 1, 并保证唯一性。tokenExpire
:Token 的有效时长(秒),最长有效期为 24 小时。joinChannelPrivilegeExpire
:加入频道权限的有效时长(秒)。pubAudioPrivilegeExpire
:在频道内发布音频流权限的有效时长(秒)。pubVideoPrivilegeExpire
:在频道内发布视频流权限的有效时长(秒)。pubDataStreamPrivilegeExpire
:在频道内发布数据流权限的有效时长(秒)。
- 上述不同权限的过期时间长度均从 Token 生成开始计算。
- 声网建议将 Token 的过期时间与其他权限的过期时间设为一致。
- 在频道中发布音视频流和数据流的权限仅在开启连麦鉴权服务后才生效。如果加入频道的权限过期时间早于发布音频流权限的过期时间,则在加入频道的权限过期后,用户会被踢出频道。