Skip to main content

AccessToken upgrade guide

To secure user access, integrate token authentication into your Voice Calling identity management system. This guide shows you how to use Agora token generation libraries to create access tokens.

Understand the tech

A token contains the following information:

  • The App ID for your project
  • The App certificate for your project
  • Channel name
  • User ID
  • User permissions, such as whether they can send or receive streams
  • Token expiration Unix timestamp

When a user attempts to connect to an Agora channel, your app requests a token from your authentication system. Your authentication system uses Agora libraries to generate a token specific to the user and the channel, then sends it to your app. The app then sends this token to Agora SD-RTN™ with the request to join a channel. Agora SD-RTN™ validates the token and adds the user to the channel. The following diagram shows the authentication call flow between your app, your authentication system and Agora SD-RTN™:

Token authentication flow

token authentication flow

Prerequisites

Before starting, ensure that you have:

  • Implemented the SDK quickstart in your project.

  • The following information from Agora Console:

    • App ID: A unique string generated by Agora that identifies your project.
    • App Certificate: A string generated by Agora Console to enable token authentication. To obtain the App Certificate for your project, enable primary certificate.

Deploy a token server

This section shows you how to quickly deploy a token server based on AccessToken2. If you already have a token server that uses AccessToken skip to Upgrade to AccessToken2..

The following example uses Golang. Before starting, ensure that you have Golang version 1.14 or above.

Follow these steps to build and run a token generator locally:

  1. Create a new token-server folder. Create a server.go file inside the folder and paste the following Golang sample code into the file. Replace the values for appID and appCertificate with your App ID and App certificate.

    Sample code for a token server
    package main import (     rtctokenbuilder "github.com/AgoraIO/Tools/DynamicKey/AgoraDynamicKey/go/src/rtctokenbuilder2"     "fmt"     "log"     "net/http"     "encoding/json"     "errors"     "strconv" ) type rtc_int_token_struct struct{     Uid_rtc_int uint32 `json:"uid"`     Channel_name string `json:"ChannelName"`     Role uint32 `json:"role"` } var rtc_token string var int_uid uint32 var channel_name string var role_num uint32 var role rtctokenbuilder.Role // Use RtcTokenBuilder to generate RTC Token func generateRtcToken(int_uid uint32, channelName string, role rtctokenbuilder.Role){     appID := "<Your App ID>"     appCertificate := "<Your App Certificate>"     // Ensure that the expiration time of the token is later than the permission expiration time. Permission expiration time, unit is seconds     tokenExpireTimeInSeconds := uint32(40)     // The token-privilege-will-expire callback is triggered 30 seconds before the permission expires.     // For demonstration purposes, set the expiration time to 40 seconds. You can see the process of the client automatically updating the Token     privilegeExpireTimeInSeconds := uint32(40)     result, err := rtctokenbuilder.BuildTokenWithUid(appID, appCertificate, channelName, int_uid, role, tokenExpireTimeInSeconds, privilegeExpireTimeInSeconds)     if err != nil {         fmt.Println(err)     } else {         fmt.Printf("Token with uid: %s\n", result)         fmt.Printf("uid is %d\n", int_uid )         fmt.Printf("ChannelName is %s\n", channelName)         fmt.Printf("Role is %d\n", role)     }     rtc_token = result } func rtcTokenHandler(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_int rtc_int_token_struct     var unmarshalErr *json.UnmarshalTypeError     int_decoder := json.NewDecoder(r.Body)     int_err := int_decoder.Decode(&t_int)     if (int_err == nil) {                 int_uid = t_int.Uid_rtc_int                 channel_name = t_int.Channel_name                 role_num = t_int.Role                 switch role_num {                     case 1:                         role = rtctokenbuilder.RolePublisher                     case 2:                         role = rtctokenbuilder.RoleSubscriber                 }     }     if (int_err != nil) {         if errors.As(int_err, &unmarshalErr){                 errorResponse(w, "Bad request. Wrong type provided for field " + unmarshalErr.Value  + unmarshalErr.Field + unmarshalErr.Struct, http.StatusBadRequest)                 } else {                 errorResponse(w, "Bad request.", http.StatusBadRequest)             }         return     }     generateRtcToken(int_uid, channel_name, role)     errorResponse(w, rtc_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(){     // Use int type uid to generate RTC Token     http.HandleFunc("/fetch_rtc_token", rtcTokenHandler)     fmt.Printf("Starting server at port 8082")     if err := http.ListenAndServe(":8082", nil); err != nil {         log.Fatal(err)     } }
  2. Open the terminal, go to the token-server folder path, and run the following command line to create a go.mod file for your token generator. This file defines the import path and dependencies:


    _1
    go mod init sampleServer

  3. Run the following command to install dependencies.


    _1
    go get github.com/AgoraIO/Tools/DynamicKey/AgoraDynamicKey/go/src/rtctokenbuilder2

  4. Run the following command to start the token generator:


    _1
    go run server.go

After the token generator is deployed successfully, your terminal returns the token generated based on the App ID and App certificate you filled in.

Reference

This section contains content that completes the information on this page, or points you to documentation that explains other aspects to this product.

Upgrade to AccessToken2

If your current token server implementation uses AccessToken, follow these steps to upgrade your server to AccessToken2.

  1. Replace the import rtctokenbuilder declaration with the following code and delete the declaration that imports time:


    _13
    import (
    _13
    // Replace
    _13
    // rtctokenbuilder "github.com/AgoraIO/Tools/DynamicKey/AgoraDynamicKey/go/src/RtcTokenBuilder"
    _13
    rtctokenbuilder "github.com/AgoraIO/Tools/DynamicKey/AgoraDynamicKey/go/src/rtctokenbuilder2"
    _13
    "fmt"
    _13
    "log"
    _13
    "net/http"
    _13
    // delete
    _13
    // "time"
    _13
    "encoding/json"
    _13
    "errors"
    _13
    "strconv"
    _13
    )

  2. Remove the statement that generates the timestamp and add tokenExpireTimeInSeconds and privilegeExpireTimeInSeconds related code:


    _7
    // expireTimeInSeconds := uint32(40)
    _7
    // Get the current timestamp
    _7
    // currentTimestamp := uint32(time.Now().UTC().Unix())
    _7
    // Timestamp when the token expires.
    _7
    // expireTimestamp := currentTimestamp + expireTimeInSeconds
    _7
    tokenExpireTimeInSeconds := uint32(40)
    _7
    privilegeExpireTimeInSeconds := uint32(40)

  3. Update tokenbuilder method code:


    _6
    // Code before updating
    _6
    // result, err := rtctokenbuilder.BuildTokenWithUID(appID, appCertificate, channelName, int_uid, role, expireTimestamp)
    _6
    // Updated code
    _6
    // Change BuildTokenWithUID to BuildTokenWithUid
    _6
    // Change expireTimestamp to tokenExpireTimeInSeconds and privilegeExpireTimeInSeconds
    _6
    result, err := rtctokenbuilder.BuildTokenWithUid(appID, appCertificate, channelName, int_uid, role, tokenExpireTimeInSeconds, privilegeExpireTimeInSeconds)

  4. Remove unsupported roles


    _14
    switch role_num {
    _14
    // delete
    _14
    // case 0:
    _14
    // Deprecated. RoleAttendee and RolePublisher have the same permissions
    _14
    // role = rtctokenbuilder.RoleAttendee
    _14
    case 1:
    _14
    role = rtctokenbuilder.RolePublisher
    _14
    case 2:
    _14
    role = rtctokenbuilder.RoleSubscriber
    _14
    // delete
    _14
    // case 101:
    _14
    // Deprecated. RoleAdmin and RolePublisher have the same permissions
    _14
    // role = rtctokenbuilder.RoleAdmin
    _14
    }

See also

Voice Calling