使用 Token 鉴权
鉴权是指在用户访问你的系统前,对其进行身份校验。用户在使用声网服务,如加入教室时,声网使用 Token 对其鉴权。
为提供更好的鉴权体验和安全性保障,声网自 2022 年 8 月 18 日推出新版 Token:AccessToken2。我们推荐使用 AccessToken2,同时也兼容 AccessToken。
本文提供如何使用 AccessToken2 在服务端部署一个 Token 生成器,如何在客户端使用 Token 鉴权,以及相关的参考信息。
鉴权原理
下图展示了鉴权的基本流程:
声网 Token 在 App 服务器上生成,其最长有效期为 24 小时。当用户从你的 App 客户端登录到灵动课堂服务器时,声网平台会读取该 Token 中包含的信息,并进行校验。Token 包含以下信息:
- 你在声网控制台创建项目时生成的 App ID
- 灵动课堂用户 ID
- Token 过期的 Unix 时间戳
前提条件
开始前,请确保你的项目或使用的声网产品满足如下条件:
-
一个有效的声网账户。
-
已开启 App 证书的声网项目。
-
Golang 1.14 以上版本,
GO111MODULE
设置为开启。信息如果你使用的是 Go 1.16 及以上版本,
GO111MODULE
已默认开启。详情请参考 New module changes in Go 1.16。
实现鉴权流程
本节介绍如何使用声网提供的 Token 生成器生成并提供 Token,对用户及其权限进行校验。
获取 App ID 及 App 证书
本节介绍如何获取生成 Token 所需的安全信息,如你的项目的 App ID 及 App 证书。
1. 获取 App ID
成功创建项目后,声网会给每个项目自动分配一个 作为项目唯一标识。你可以直接在总览页面的项目信息栏,点击 App ID 右侧的复制按钮来获取当前项目的 App ID。
你需要保存好复制的 App ID,后续调用 API 进行初始化等操作时需要传入你获取的 App ID。
2. 获取 App 证书
-
在声网控制台的项目管理页面,找到你的项目,点击配置。
-
点击主要证书下面的复制图标,即可获取项目的 App 证书。
为 AccessToken2 部署 Token 服务器
Token 需要在你的服务端部署生成。当客户端发送请求时,服务端部署的 Token 生成器会生成相应的 Token,再发送给客户端。
本节展示如何使用 Golang 在你的本地设备上搭建并运行一个 Token 服务器。
此示例服务器仅用于演示,请勿用于生产环境中。
-
创建一个
server.go
文件,然后贴入如下代码。将其中的Your_App_ID
和Your_Certificate
替换为你的 App ID 和 App 证书。Gopackage main
import (
apaastokenbuilder "github.com/AgoraIO/Tools/DynamicKey/AgoraDynamicKey/go/src/apaastokenbuilder"
"fmt"
"log"
"net/http"
"time"
"encoding/json"
"errors"
"strconv"
)
type apaas_token_struct struct {
roomUuid string `json:"roomUuid"`
userUuid string `json:"userUuid"`
role int `json:"role"`
}
var apaasToken string
func generateApaasToken(roomUuid string, userUuid string, role int) {
// 把 "Your_App_ID" 替换为你的 App ID
appID := "Your_App_ID"
// 把 "Your_Certificate" 替换为你的 App 证书
appCertificate := "Your_Certificate"
expire := uint32(3600)
result, err := apaastokenbuilder.BuildRoomUserToken(appID, appCertificate, roomUuid, userUuid, role, expire)
if err != nil {
fmt.Println(err)
} else {
fmt.Printf("ApaasToken: %s\n", result)
apaasToken = result
}
}
func apaasTokenHandler(w http.ResponseWriter, r *http.Request) {
w.Header().Set("Content-Type", "application/json;charset=UTF-8")
w.Header().Set("Access-Control-Allow-Origin", "*")
w.Header().Set("Access-Control-Allow-Methods", "POST, OPTIONS");
w.Header().Set("Access-Control-Allow-Headers", "*");
if r.Method == "OPTIONS" {
w.WriteHeader(http.StatusOK)
return
}
if r.Method != "POST" && r.Method != "OPTIONS" {
http.Error(w, "Unsupported method. Please check.", http.StatusNotFound)
return
}
var t_apaas_str apaas_token_struct
var unmarshalErr *json.UnmarshalTypeError
str_decoder := json.NewDecoder(r.Body)
apaas_err := str_decoder.Decode(&t_apaas_str)
if (apaas_err != nil) {
if errors.As(apaas_err, &unmarshalErr) {
errorResponse(w, "Bad request. Please check your params.", http.StatusBadRequest)
} else {
errorResponse(w, "Bad request.", http.StatusBadRequest)
}
return
}
generateRtmToken(t_apaas_str.roomUuid,t_apaas_str.userUuid,t_apaas_str.role)
errorResponse(w, apaasToken, http.StatusOK)
log.Println(w, r)
}
func errorResponse(w http.ResponseWriter, message string, httpStatusCode int) {
w.Header().Set("Content-Type", "application/json")
w.Header().Set("Access-Control-Allow-Origin", "*")
w.WriteHeader(httpStatusCode)
resp := make(map[string]string)
resp["token"] = message
resp["code"] = strconv.Itoa(httpStatusCode)
jsonResp, _ := json.Marshal(resp)
w.Write(jsonResp)
}
func main() {
// 处理路由
http.HandleFunc("/fetch_apaas_token", apaasTokenHandler)
fmt.Printf("Starting server at port 8082\n")
if err := http.ListenAndServe(":8082", nil); err != nil {
log.Fatal(err)
}
} -
go.mod
文件定义导入路径及依赖项。运行如下命令来为你的 Token 服务器创建go.mod
文件:Shell$ go mod init sampleServer
-
运行如下命令行安装依赖:
Shell$ go get
-
运行如下命令行启动服务器:
Shell$ go run server.go
使用 AccessToken2 鉴权
本节以 Web 端灵动课堂为例,展示如何使用 Token 对客户端的用户进行鉴权。
下列参考代码来自灵动课堂 Web 端源码 packages/agora-demo-app/src/pages/home/index.tsx
。
-
向集成了声网 Token 生成器的服务端发起 Token 请求。
TypeScriptconst { token, appId } = await roomApi.getCredentialNoAuth({
userUuid,
roomUuid,
role: userRole,
}); -
将请求成功后获取到的 Token 用于创建
launchOption
对象。TypeScriptconst launchOption = {
appId,
sdkDomain,
pretest: true,
courseWareList: [],
language: language as LanguageEnum,
userUuid: `${userUuid}`,
rtmToken: token,
roomUuid: `${roomUuid}`,
roomType: roomType,
roomName: `${roomName}`,
userName: userName,
roleType: userRole,
region: region as EduRegion,
duration: +duration * 60,
latencyLevel: 2,
shareUrl,
}; -
调用
launch
方法,使用 Token 加入课堂。TypeScriptAgoraEduSDK.launch(dom, launchOption);
参考
AccessToken2 生成器代码
声网在 GitHub 上提供一个开源的 AgoraDynamicKey 仓库,支持使用 C++、Java、Go 等语言在你自己的服务器上生成 Token。
App 全局 Token
作用域为 App 全局操作,如创建教室,设置和查询房间等。
语言 | 算法 | 核心方法 | 示例代码 |
---|---|---|---|
C++ | HMAC-SHA256 | BuildAppToken | N/A |
Go | HMAC-SHA256 | BuildAppToken | sample.go |
Java | HMAC-SHA256 | buildAppToken | ApaasTokenBuilderSample.java |
Node.js | HMAC-SHA256 | buildAppToken | ApaasTokenSample.js |
PHP | HMAC-SHA256 | buildAppToken | ApaasTokenBuilderSample.php |
Python 2 | HMAC-SHA256 | build_app_token | apaas_token_builder_sample.py |
Python 3 | HMAC-SHA256 | build_app_token | apaas_token_builder_sample.py |
指定房间指定用户(客户端使用)
作用域为指定房间中的指定用户,在客户端 SDK 启动时传入,可以帮助用户打通灵动课堂及 RTM 用户登录的 token。
语言 | 算法 | 核心方法 | 示例代码 |
---|---|---|---|
C++ | HMAC-SHA256 | BuildRoomUserToken | N/A |
Go | HMAC-SHA256 | BuildRoomUserToken | sample.go |
Java | HMAC-SHA256 | buildRoomUserToken | ApaasTokenBuilderSample.java |
Node.js | HMAC-SHA256 | buildRoomUserToken | ApaasTokenSample.js |
PHP | HMAC-SHA256 | buildRoomUserToken | ApaasTokenBuilderSample.php |
Python 2 | HMAC-SHA256 | build_room_user_token | apaas_token_builder_sample.py |
Python 3 | HMAC-SHA256 | build_room_user_token | apaas_token_builder_sample.py |
AccessToken 生成器代码
如果你使用的是 AccessToken,可参考以下示例代码:
语言 | 算法 | 核心方法 | 示例代码 |
---|---|---|---|
C++ | HMAC-SHA256 | buildToken | RtmTokenBuilderSample.cpp |
Go | HMAC-SHA256 | buildToken | sample.go |
Java | HMAC-SHA256 | buildToken | RtmTokenBuilderSample.java |
Node.js | HMAC-SHA256 | buildToken | RtmTokenBuilderSample.js |
PHP | HMAC-SHA256 | buildToken | RtmTokenBuilderSample.php |
Python 2 | HMAC-SHA256 | buildToken | RtmTokenBuilderSample.py |
Python 3 | HMAC-SHA256 | buildToken | RtmTokenBuilderSample.py |
开发注意事项
参数匹配
生成 Token 时填入的用户 ID,需要和登录灵动课堂系统时填入的用户 ID 一致。
App 证书与 Token
生成 Token 需要先在控制台启用对应项目的 App 证书。项目一旦开启了 App 证书,就必须使用 Token 鉴权。