部署 Token 服务器

更新时间不可用

了解如何在实时消息 RTM 中部署 Token 服务器,包括适用场景、配置步骤、实现要点和注意事项。

Token 需要在你的服务端部署生成。当客户端发送请求时,服务端部署的 Token Generator 会生成相应的 Token,再发送给客户端。本文展示如何为 AccessToken2 在服务端部署一个 RTM Token 生成器。

前提条件

开始前,请确保你的项目或使用的声网产品满足如下条件:

  • Golang 1.14 以上版本,GO111MODULE 设置为开启。

    信息

    如果你使用的是 Go 1.16 及以上版本,GO111MODULE 已默认开启。详见 New module changes in Go 1.16。

实现部署 Token 服务器

本节展示如何使用 Golang 在你的本地设备上搭建并运行一个 Token 服务器,生成并提供 Token。

信息

此示例服务器仅用于演示,请勿用于生产环境中。

  1. 创建一个 server.go 文件,然后贴入如下代码。将其中的 Your_App_ID 和 Your_Certificate 替换为你的 App ID 和 App 证书。

    Go
    package main
    
    import (
        rtmtokenbuilder "github.com/AgoraIO/Tools/DynamicKey/AgoraDynamicKey/go/src/rtmtokenbuilder2"
        "fmt"
        "log"
        "net/http"
        "time"
        "encoding/json"
        "errors"
        "strconv"
    )
    
    type rtm_token_struct struct{
        Uid_rtm string `json:"uid"`
    }
    
    var rtm_token string
    var rtm_uid string
    
    // 使用 RtmTokenBuilder 来生成 RTM Token
    func generateRtmToken(rtm_uid string){
    
        appID := "Your_App_ID"
        appCertificate := "Your_Certificate"
        // AccessToken2 过期的时间,单位为秒
        expireTimeInSeconds := uint32(3600)
        currentTimestamp := uint32(time.Now().UTC().Unix())
        expireTimestamp := currentTimestamp + expireTimeInSeconds
    
        result, err := rtmtokenbuilder.BuildToken(appID, appCertificate, rtm_uid, expireTimestamp)
        if err != nil {
            fmt.Println(err)
        } else {
            fmt.Printf("Rtm Token: %s\n", result)
    
        rtm_token = result
    
        }
    }
    
    func rtmTokenHandler(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_rtm_str rtm_token_struct
            var unmarshalErr *json.UnmarshalTypeError
            str_decoder := json.NewDecoder(r.Body)
            rtm_err := str_decoder.Decode(&t_rtm_str)
    
            if (rtm_err == nil) {
                rtm_uid = t_rtm_str.Uid_rtm
            }
    
            if (rtm_err != nil) {
                if errors.As(rtm_err, &unmarshalErr){
                errorResponse(w, "Bad request. Please check your params.", http.StatusBadRequest)
                } else {
                errorResponse(w, "Bad request.", http.StatusBadRequest)
            }
            return
        }
    
            generateRtmToken(rtm_uid)
            errorResponse(w, rtm_token, 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(){
        // 使用 int 型 uid 生成 RTM Token
        http.HandleFunc("/fetch_rtm_token", rtmTokenHandler)
    
        fmt.Printf("Starting server at port 8082\n")
    
        if err := http.ListenAndServe(":8082", nil); err != nil {
            log.Fatal(err)
        }
    }
  2. go.mod 文件定义导入路径及依赖项。运行如下命令来为你的 Token 服务器创建 go.mod 文件:

    Shell
    $ go mod init sampleServer
  3. 运行如下命令行安装依赖:

    Shell
    $ go get
  4. 运行如下命令行启动服务器:

    Shell
    $ go run server.go

信息

如果你需要生成一个同时具备 RTC 和 RTM 权限的 Token,请参考如何生成具备 RTC 和 RTM 权限的 Token?。

参考

AccessToken2 生成器代码

声网在 GitHub 上提供一个开源的 AgoraDynamicKey 仓库,支持使用 C++、Java、Go 等语言在你自己的服务器上生成 Token。

语言算法核心方法示例代码
C++HMAC-SHA256buildTokenRtmTokenBuilder2Sample.cpp
GoHMAC-SHA256buildTokensample.go
JavaHMAC-SHA256buildTokenRtmTokenBuilder2Sample.java
PHPHMAC-SHA256buildTokenRtmTokenBuilder2Sample.php
Python 2HMAC-SHA256buildTokenRtmTokenBuilder2Sample.py
Python 3HMAC-SHA256buildTokenRtmTokenBuilder2Sample.py
表格内容超出当前宽度,可横向滚动查看更多列。

BuildToken API 参考

本节介绍生成 AccessToken2 的 API 参数和描述。以 Golang 为例:

Go
func BuildToken(appId string, appCertificate string, userId string, expire uint32) (string, error) {
    token := accesstoken.NewAccessToken(appId, appCertificate, expire)

    serviceRtm := accesstoken.NewServiceRtm(userId)
    serviceRtm.AddPrivilege(accesstoken.PrivilegeLogin, expire)
    token.AddService(serviceRtm)

    return token.Build()
}
参数描述
appId你在声网控制台创建项目时生成的 App ID。
appCertificate你的 App 证书。
userId用户 ID,用于标识用户或设备。为区分各用户和设备,你需要确保 userId 全局唯一,并且在用户或设备的生命周期内保持不变。
expireToken 的有效时长(秒),最长有效期为 24 小时。
表格内容超出当前宽度,可横向滚动查看更多列。