Token 也称为动态密钥,是在加入频道时用于校验用户权限的一组字符串;鉴权是指在用户访问你的系统前,对其进行身份校验。用户在使用声网服务,如加入音视频通话或登录信令系统时,声网会使用 Token 对其鉴权。
我们为这种方式提供了一个较为形象的比喻,即:
某个展览馆需要游客实名认证后,获取专属入场券才可参观。游客在完成实名认证后可以获取到具备有效期限制的专属入场券,在进场时提供在有效期内的入场券,方能进场。其中:
展览馆相当于声网的服务,即音视频频道或信令系统等;
专属入场券相当于 Token;
实名认证步骤相当于结合 声网 AppID、频道号、用户 ID 等信息 获取到专属 Token 的步骤;
进场时校验入场券相当于鉴权,即校验 Token 是否和 声网 AppID、频道号、用户 ID 等信息匹配,且在有效期内。
声网的产品和服务中大部分采用 Token 鉴权的方式。下面,我们针对如何生成和使用 Token,以及 Token 鉴权中常见的问题进行详细的讲解。
在了解如何生成和使用 Token 前,需要先了解 Token 鉴权的原理。
如图所示,共分为 9 个步骤:
1.客户端根据需要,向 app 服务端申请 Token
2.App 服务端生成并返回 Token
3.客户端以 UID、频道名以及获取到的 Token 加入频道
4.声网平台读取该 Token 中包含的信息,并进行校验
5.客户端收到加入频道成功回调,并获取用户 UID
6.Token 最大有效期为 24 小时。当即将过期时,客户端会收到 Token 即将过期的回调
7.此时,如果客户端需要继续进行音视频互动,需要申请新的 Token
8.App 服务端生成并返回 Token
9.客户端更新 Token
这个过程中,用户需要自行实现步骤 1、2、3、7、8、9 的代码逻辑。
其中,对应的 Token 包含以下信息:
你在声网控制台创建项目时生成的 App ID
频道名
用户 ID
用户权限,如是否能发流或收流
Token 的过期时间
可以看到,在用户加入频道前,客户端需要先向服务器申请 Token,并在 服务器 生成 Token,且 Token 必须与 需要加入频道的用户所对应的 AppID、频道名、用户 ID(UID)信息、用户权限 (是否能发流或收流) 一一对应,并且确保生成的 Token 在有效期内。然后才能以 UID、频道号 和 Token 加入对应频道。
向服务器申请 Token,可以通过向服务器发送 GET 请求等方式自行实现,以下文章以供参考:
https://www.rtcdeveloper.cn/cn/community/blog/22929
https://www.rtcdeveloper.cn/cn/community/blog/24981
https://www.rtcdeveloper.cn/cn/community/blog/19790
https://www.rtcdeveloper.cn/cn/community/blog/20102
https://www.rtcdeveloper.cn/cn/community/blog/20024
https://www.rtcdeveloper.cn/cn/community/blog/20709
https://www.rtcdeveloper.cn/cn/community/blog/25430
生成 Token,可以使用声网提供的 Demo 实现,Demo 地址请参考:Token 生成器代码
请务必注意:例如用户使用 UID=123456(int 型)加入频道 ChannelName="test",那么生成 Token 时传入的参数 UID 和 ChannelName 必须是相对应的,即 UID=123456(int 型)且 ChannelName="test",否则会导致鉴权失败。
Token 最大有效期为 24 小时。当即将过期时,客户端会收到 Token 即将过期的回调;Token 过期时,SDK 会触发 Token 过期回调。具体处理方式如下:
在 Token 过期前 30 秒,SDK 会触发 tokenPrivilegeWillExpire 回调。收到该回调后,客户端需要从服务器获取新的 Token 并调用 renewToken 将新生成的 Token 传给 SDK。
Token 过期时,SDK 会触发 rtcEngineRequestToken 回调。收到该回调后,客户端需要从服务器获取新的 Token 并调用 joinChannel 方法,再使用新的 Token 重新加入频道。
一般来说,我们建议在 Token 过期前,及时更新 Token,即从服务器获取新的 Token 并调用 renewToken 将新生成的 Token 传给 SDK。
当你的声网项目中不存在无证书并且启用了主要/次要证书,则表示你选择使用动态密钥 Token 对用户进行鉴权。
由于 Token 具有一定的时效性,因此 app 在运行过程中,你有可能会收到如下与 Token 相关的错误码或事件回调。本文对这些事件进行了梳理,提供触发的原因以及解决方法,帮助你在 App 出现异常时进行问题排查。
问题描述:
Native 端:SDK 在初始化声网服务时返回错误码 ERR_INVALID_APP_ID(101);或调用 joinChannel 方法加入频道时,SDK 回调 onError 事件,并报告错误码 ERR_INVALID_APP_ID(101)。
Web 端:在初始化 声网服务或调用 Client.join 方法加入频道时,Console 控制台打印错误码 ERR_INVALID_VENDOR_KEY(101)。
问题原因:
不是有效的 App ID,一般是由于 App ID 的数据类型不对引起的。
解决方法:
建议检查 App ID 数据格式是否有效。声网的 App ID 为 String 型,请使用正确数据类型的 App ID,重新初始化声网服务。
问题描述:
Native 端:调用 joinChannel 方法加入频道时,SDK 回调 onError 事件,并报告错误码 ERR_TOKEN_EXPIRED(109)。
Web 端:调用 Client.join 方法加入频道时,Console 控制台打印错误码 ERR_DYNAMIC_KEY_TIMEOUT(109) 或 ERR_DYNAMIC_KEY_EXPIRED(118)。
问题原因:
Token 过期。
解决方法:
Token 一旦过期,你就需要在服务端重新生成一个 Token,然后调用 renewToken 方法尝试重新加入频道。
问题描述:
Native 端:调用 joinChannel 方法加入频道时,SDK 回调 onError 事件,并报告错误码 ERR_INVALID_TOKEN(110)。
Web 端:调用 Client.join 方法加入频道时,Console 控制台打印错误码 ERR_NO_AUTHORIZED(110)。
问题原因:
生成的 Token 无效。一般有以下原因:
你的声网项目中不存在无证书并且启用了主要/次要证书,但是加入频道时却未传入 Token;或者项目未开启主要/次要证书,就试图使用 Token 加入频道。
你在服务端生成 Token 时填入的 App ID、用户 ID 和频道名,与你初始化和加入频道时填入的 App ID、用户 ID 和频道名不匹配。
解决方法:
在加入频道前,请确认你在初始化时填入的 App ID 对应的项目是否已启用主要/次要证书。
如果未启用主要/次要证书,则不能使用 Token 加入频道。
如果项目中存在无证书并且已启用主要/次要证书,则既可以仅使用 App ID 加入频道,也可以使用主要/次要证书生成的 Token 加入频道。
如果项目中不存在无证书并且已启用主要/次要证书,则必须使用 Token 加入频道。
当确认使用 Token 加入频道时,还需要确认:
用于生成 Token 的 App ID 和初始化服务时填入的 App ID 一致。
用于生成 Token 的用户 ID 和加入频道时填入的用户 ID 一致,且数据类型也一致。
用于生成 Token 的频道名和加入频道时填入的频道名一致。
该错误码仅适用于 RTC Web SDK。
问题描述:
Web 端调用 Client.join 方法加入频道时,Console 控制台打印错误码 ERR_STATIC_USE_DYNAMIC_KEY(119)。
问题原因:
表示静态厂商使用了动态密钥。一般是由于使用的 App ID 对应的声网项目未启用主要/次要证书,却试图使用 Token 加入频道引起。
解决方法:
对于未开启主要/次要证书的项目,你可以不使用 Token 加入频道。你也可以先启用主要/次要证书,然后在服务端生成 Token 后重新加入频道。
该错误码仅适用于 RTC Web SDK。
问题描述:
Web 端调用 Client.join 方法加入频道时,Console 控制台打印错误码 ERR_DYNAMIC_USE_STATIC_KEY(120)。
问题原因:
表示动态厂商使用了静态密钥。一般是由于使用的 App ID 对应的声网项目中不存在无证书并且已启用主要/次要证书,加入频道时却没有传入 Token 引起。
解决方法:
如果 App ID 对应的项目中不存在无证书并且已启用主要/次要证书,则必须使用 Token 进行鉴权。你也可以换一个没有启用主要/次要证书的项目的 App ID,然后尝试重新加入频道。
为保证通信体验,声网提供如下两个回调,提醒用户 Token 即将过期或已经过期:
onTokenPrivilegeWillExpire:该回调表示 Token 即将在 30 秒内失效。收到这个回调时,你需要在服务端重新生成 Token,然后调用 renewToken 方法,将新生成的 Token 传给 SDK。
onRequestToken(Web 平台为 onTokenPrivilegeDidExpire):该回调表示 Token 已经失效。收到这个回调时,你需要在服务端重新生成 Token,然后调用 joinChannel 方法重新尝试加入频道。