For AI agents: see the complete documentation index at /llms.txt.
Secure authentication with tokens
Updated
Retrieve tokens generated by an authentication token server to securely connect to Signaling.
Authentication is the act of validating the identity of a user before they access a system. Agora uses digital tokens to authenticate users and their privileges before they access Signaling. A token is a string used to verify user privileges when logging in or joining a channel. When a user connects to Agora and passes in the token, the server verifies the user's identity and permissions based on the information in the token.
This page shows you how to set up a token server, and use it to connect securely to Signaling.
Understand the tech
Signaling provides two types of channels:
- Message channels: To join a message channel, you only need to use an RTM token when calling the login method. An RTM token is valid only for the user Id that you use to generate it.
- Stream channels: To join a stream channel, you use an RTC token when calling the join method. An RTC token is valid only for the channel name and the user Id that you used to generate it.
The following figure shows the call flow you implement to create step-up-authentication with Signaling:
Authentication workflow
To log in to Signaling, your app retrieves an RTM token from the token server in your security infrastructure. Your app then sends this token to Agora SDRTN® for authentication. Agora SDRTN® validates the token and reads the user and project information stored in the token. To join a stream channel you request an RTC token from the server by supplying a user Id and a channel name. You do not need an authentication token to subscribe to a message channel.
A token contains the following information:
- The App ID of your Agora project
- The user Id of the user to be authenticated
- The stream channel name (RTC token only)
- The Unix timestamp indicating when the token will expire
Prerequisites
Ensure that you have:
-
Integrated the Signaling SDK in your project, and implemented the framework functionality from the SDK quickstart page.
-
The following information from Agora Console:
- App ID: A unique string provided by Agora that identifies your project.
- App certificate: A string generated using Agora Console to enable token authentication. To obtain the App certificate for your project, enable primary certificate.
Implement basic authentication
In the SDK quickstart, the app uses an authentication token obtained from Agora Console to join a channel. In a production environment, your app retrieves this token from a token server.
Token generation code
Agora provides an open source token generator code repository on GitHub. The repository contains code samples, based on the HMAC-SHA256 algorithm, in the following languages to generate tokens on your own server:
| Language | Core method | Sample code |
|---|---|---|
| Go | buildToken | sample.go |
| PHP | buildToken | RtmTokenBuilder2Sample.php |
| Python 2 | buildToken | RtmTokenBuilder2Sample.py |
| Python 3 | buildToken | RtmTokenBuilder2Sample.py |
| C++ | buildToken | RtmTokenBuilder2Sample.cpp |
| Java | buildToken | RtmTokenBuilder2Sample.java |
Generate a token
This section shows you how to generate an RTM token using Go language AccessToken2 code from the GitHub repository. To use another language refer to the code samples and READMEs in the Github repository. To generate an RTC token refer to Secure authentication with tokens.
Before proceeding, make sure that you have:
- Installed Go 1.14 or above
- If you are using a Go version lower than 1.16, set the
GO111MODULEenvironment variable toon.
Take the following steps to set up a token generation server:
Create server.go
Create a server.go file containing the following code. Replace Your_App_ID and Your_App_Certificate with your app ID and app certificate from Agora Console.
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
// Use RtmTokenBuilder to generate an RTM Token
func generateRtmToken(rtm_uid string){
appID := "Your_App_ID"
appCertificate := "Your_App_Certificate"
// Token expiration time in seconds
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(){
// Use an int type uid to generate an 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)
}
}Refer to the BuildToken API reference for parameter descriptions.
Create go.mod
The go.mod file defines the import paths and dependencies. To create this file for your token server, run the following command:
go mod init sampleServerInstall dependencies
To install the dependencies, run the following command:
go getStart the server
To start the server, execute:
go run server.goImportant
This sample server is for development purposes only. It should not be used in a production environment.
Login with a token
To log in to Signaling using an RTM token, fetch a token from your token server and pass it to the SDK by calling login. Refer to the following sample code:
// Whether to enable the Token update loop
let started = true;
function sleep(time) {
return new Promise((resolve) => setTimeout(resolve, time));
}
function fetchToken(uid) {
return new Promise(function (resolve) {
axios
.post(
"http://<Your Host URL and port>/fetch_rtm_token",
{
uid: uid,
},
{
headers: {
"Content-Type": "application/json; charset=UTF-8",
},
},
)
.then(function (response) {
const token = response.data.token;
resolve(token);
})
.catch(function (error) {
console.log(error);
});
});
}
async function loginRTM() {
// Your App ID
const appID = "<Your App ID>";
// Set RTM user ID
const uid = "1234";
// Get Token
const token = await fetchToken(uid);
// Initialize the client
const client = new AgoraRTM.RTM(appID, uid);
// Display connection status changes
client.on('status', function (state, reason) {
console.log("State changed To: " + state + " Reason: " + reason)
});
// Log in to the RTM system
await client.login({ token });
while (started) {
// Update the Token every 30 seconds. This update frequency is for demonstration purposes; in production, it's recommended to update every hour.
await sleep(30 * 1000);
const newToken = await fetchToken(uid);
await client.renewToken(newToken);
let currentDate = new Date();
let time = currentDate.getHours() + ":" + currentDate.getMinutes() + ":" + currentDate.getSeconds();
console.log("Renew RTM token at " + time);
}
}
loginRTM();In the sample code:
- Replace
<Your App ID>with your actual app ID. - Replace
<Your host URL and port>with the actual host URL and port of your token server, for example,10.123.123.123:8082.
Note
- The user ID and app ID you use to initialize the Signaling client instance must be the same as the user ID and app ID you use on the token server to generate a token.
- When integrating the Signaling SDK into your app, ensure that the app certificate is properly configured. The app certificate serves as a key authentication mechanism between your app and Agora SDRTN® to ensure secure and reliable communication.
Join a stream channel using a token
To join a stream channel using a token, fetch an RTC token from your token server and pass it to the SDK when you call join. For details, refer to the API reference.
Token expiration and renewal
You configure the validity period of an RTM token in your token generator according to your business needs. The maximum validity period of a token is 24 hours. When an RTM token is about to expire, the tokenPrivilegeWillExpire callback is triggered 30 seconds before the expiration time. When you receive this callback, retrieve a fresh RTM token from your token server, and call renewToken to pass the new token to the SDK.
If the token expires, the SDK triggers the linkState callback with the following information:
- Current status
currentState:FAILED - The operation that triggers this state transition
operation:SERVER_REJECT - Reason for state change:
reason:Ticket expired
In this case, log out of Signaling using the logout method, retrieve a fresh token, and login again.
An alternative approach to handling token expiration through the tokenPrivilegeWillExpire and linkState callbacks is to handle expiration proactively. Best practice is to update the token periodically to ensure seamless authentication and uninterrupted operation.
Reference
This section contains content that completes the information on this page, or points you to documentation that explains other aspects to this product.
BuildToken API reference
This section explains the API parameters and descriptions for generating AccessToken2 using Golang as an example:
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()
}| Parameter | Description |
|---|---|
appId | The app ID generated when you create a project in Agora Console. |
appCertificate | Your app certificate. |
userId | The user ID, used to identify a user or device. To differentiate between users and devices, ensure that the userId is globally unique and remains unchanged for the lifetime of the user or device. |
expire | The validity period of the token (in seconds). The maximum validity period is 24 hours. |
Authentication is the act of validating the identity of a user before they access a system. Agora uses digital tokens to authenticate users and their privileges before they access Signaling. A token is a string used to verify user privileges when logging in or joining a channel. When a user connects to Agora and passes in the token, the server verifies the user's identity and permissions based on the information in the token.
This page shows you how to set up a token server, and use it to connect securely to Signaling.
Understand the tech
Signaling provides two types of channels:
- Message channels: To join a message channel, you only need to use an RTM token when calling the login method. An RTM token is valid only for the user Id that you use to generate it.
- Stream channels: To join a stream channel, you use an RTC token when calling the join method. An RTC token is valid only for the channel name and the user Id that you used to generate it.
The following figure shows the call flow you implement to create step-up-authentication with Signaling:
Authentication workflow
To log in to Signaling, your app retrieves an RTM token from the token server in your security infrastructure. Your app then sends this token to Agora SDRTN® for authentication. Agora SDRTN® validates the token and reads the user and project information stored in the token. To join a stream channel you request an RTC token from the server by supplying a user Id and a channel name. You do not need an authentication token to subscribe to a message channel.
A token contains the following information:
- The App ID of your Agora project
- The user Id of the user to be authenticated
- The stream channel name (RTC token only)
- The Unix timestamp indicating when the token will expire
Prerequisites
Ensure that you have:
-
Integrated the Signaling SDK in your project, and implemented the framework functionality from the SDK quickstart page.
-
The following information from Agora Console:
- App ID: A unique string provided by Agora that identifies your project.
- App certificate: A string generated using Agora Console to enable token authentication. To obtain the App certificate for your project, enable primary certificate.
Implement basic authentication
In the SDK quickstart, the app uses an authentication token obtained from Agora Console to join a channel. In a production environment, your app retrieves this token from a token server.
Token generation code
Agora provides an open source token generator code repository on GitHub. The repository contains code samples, based on the HMAC-SHA256 algorithm, in the following languages to generate tokens on your own server:
| Language | Core method | Sample code |
|---|---|---|
| Go | buildToken | sample.go |
| PHP | buildToken | RtmTokenBuilder2Sample.php |
| Python 2 | buildToken | RtmTokenBuilder2Sample.py |
| Python 3 | buildToken | RtmTokenBuilder2Sample.py |
| C++ | buildToken | RtmTokenBuilder2Sample.cpp |
| Java | buildToken | RtmTokenBuilder2Sample.java |
Generate a token
This section shows you how to generate an RTM token using Go language AccessToken2 code from the GitHub repository. To use another language refer to the code samples and READMEs in the Github repository. To generate an RTC token refer to Secure authentication with tokens.
Before proceeding, make sure that you have:
- Installed Go 1.14 or above
- If you are using a Go version lower than 1.16, set the
GO111MODULEenvironment variable toon.
Take the following steps to set up a token generation server:
Create server.go
Create a server.go file containing the following code. Replace Your_App_ID and Your_App_Certificate with your app ID and app certificate from Agora Console.
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
// Use RtmTokenBuilder to generate an RTM Token
func generateRtmToken(rtm_uid string){
appID := "Your_App_ID"
appCertificate := "Your_App_Certificate"
// Token expiration time in seconds
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(){
// Use an int type uid to generate an 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)
}
}Refer to the BuildToken API reference for parameter descriptions.
Create go.mod
The go.mod file defines the import paths and dependencies. To create this file for your token server, run the following command:
go mod init sampleServerInstall dependencies
To install the dependencies, run the following command:
go getStart the server
To start the server, execute:
go run server.goImportant
This sample server is for development purposes only. It should not be used in a production environment.
Login with a token
To log in to Signaling using an RTM token, fetch a token from your token server and pass it to the SDK by calling login:
// Fetch a token from your token server
// Log in to Signaling
rtmClient.login("your_token", new ResultCallback<Void>() {
@Override
public void onSuccess(Void responseInfo) {
// Handle login success
}
@Override
public void onFailure(ErrorInfo errorInfo) {
// Handle errors
}
});// Fetch a token from your token server
// Log in to Signaling
rtmClient.login("your_token", object : ResultCallback<Void> {
override fun onSuccess(responseInfo: Void?) {
// Handle login success
}
override fun onFailure(errorInfo: ErrorInfo) {
// Handle errors
}
})Note
- The user ID and app ID you use to initialize the Signaling client instance must be the same as the user ID and app ID you use on the token server to generate a token.
- When integrating the Signaling SDK into your app, ensure that the app certificate is properly configured. The app certificate serves as a key authentication mechanism between your app and Agora SDRTN® to ensure secure and reliable communication.
Join a stream channel using a token
To join a stream channel using a token, fetch an RTC token from your token server and pass it to the SDK when you call join. For details, refer to the API reference.
Token expiration and renewal
You configure the validity period of an RTM token in your token generator according to your business needs. The maximum validity period of a token is 24 hours. When an RTM token is about to expire, the onTokenPrivilegeWillExpire callback is triggered 30 seconds before the expiration time. When you receive this callback, retrieve a fresh RTM token from your token server, and call renewToken to pass the new token to the SDK.
If the token expires, the SDK triggers an onLinkStateEvent callback and reports the following information:
currentState:FAILEDoperation:SERVER_REJECTreason:Ticket expired
In this case, log out of Signaling using the logout method, retrieve a fresh token, and login again.
An alternative approach to handling token expiration through the onTokenPrivilegeWillExpire and onLinkStateEvent callbacks is to handle expiration proactively. Best practice is to update the token periodically to ensure seamless authentication and uninterrupted operation.
Reference
This section contains content that completes the information on this page, or points you to documentation that explains other aspects to this product.
BuildToken API reference
This section explains the API parameters and descriptions for generating AccessToken2 using Golang as an example:
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()
}| Parameter | Description |
|---|---|
appId | The app ID generated when you create a project in Agora Console. |
appCertificate | Your app certificate. |
userId | The user ID, used to identify a user or device. To differentiate between users and devices, ensure that the userId is globally unique and remains unchanged for the lifetime of the user or device. |
expire | The validity period of the token (in seconds). The maximum validity period is 24 hours. |
Authentication is the act of validating the identity of a user before they access a system. Agora uses digital tokens to authenticate users and their privileges before they access Signaling. A token is a string used to verify user privileges when logging in or joining a channel. When a user connects to Agora and passes in the token, the server verifies the user's identity and permissions based on the information in the token.
This page shows you how to set up a token server, and use it to connect securely to Signaling.
Understand the tech
Signaling provides two types of channels:
- Message channels: To join a message channel, you only need to use an RTM token when calling the login method. An RTM token is valid only for the user Id that you use to generate it.
- Stream channels: To join a stream channel, you use an RTC token when calling the join method. An RTC token is valid only for the channel name and the user Id that you used to generate it.
The following figure shows the call flow you implement to create step-up-authentication with Signaling:
Authentication workflow
To log in to Signaling, your app retrieves an RTM token from the token server in your security infrastructure. Your app then sends this token to Agora SDRTN® for authentication. Agora SDRTN® validates the token and reads the user and project information stored in the token. To join a stream channel you request an RTC token from the server by supplying a user Id and a channel name. You do not need an authentication token to subscribe to a message channel.
A token contains the following information:
- The App ID of your Agora project
- The user Id of the user to be authenticated
- The stream channel name (RTC token only)
- The Unix timestamp indicating when the token will expire
Prerequisites
Ensure that you have:
-
Integrated the Signaling SDK in your project, and implemented the framework functionality from the SDK quickstart page.
-
The following information from Agora Console:
- App ID: A unique string provided by Agora that identifies your project.
- App certificate: A string generated using Agora Console to enable token authentication. To obtain the App certificate for your project, enable primary certificate.
Implement basic authentication
In the SDK quickstart, the app uses an authentication token obtained from Agora Console to join a channel. In a production environment, your app retrieves this token from a token server.
Token generation code
Agora provides an open source token generator code repository on GitHub. The repository contains code samples, based on the HMAC-SHA256 algorithm, in the following languages to generate tokens on your own server:
| Language | Core method | Sample code |
|---|---|---|
| Go | buildToken | sample.go |
| PHP | buildToken | RtmTokenBuilder2Sample.php |
| Python 2 | buildToken | RtmTokenBuilder2Sample.py |
| Python 3 | buildToken | RtmTokenBuilder2Sample.py |
| C++ | buildToken | RtmTokenBuilder2Sample.cpp |
| Java | buildToken | RtmTokenBuilder2Sample.java |
Generate a token
This section shows you how to generate an RTM token using Go language AccessToken2 code from the GitHub repository. To use another language refer to the code samples and READMEs in the Github repository. To generate an RTC token refer to Secure authentication with tokens.
Before proceeding, make sure that you have:
- Installed Go 1.14 or above
- If you are using a Go version lower than 1.16, set the
GO111MODULEenvironment variable toon.
Take the following steps to set up a token generation server:
Create server.go
Create a server.go file containing the following code. Replace Your_App_ID and Your_App_Certificate with your app ID and app certificate from Agora Console.
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
// Use RtmTokenBuilder to generate an RTM Token
func generateRtmToken(rtm_uid string){
appID := "Your_App_ID"
appCertificate := "Your_App_Certificate"
// Token expiration time in seconds
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(){
// Use an int type uid to generate an 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)
}
}Refer to the BuildToken API reference for parameter descriptions.
Create go.mod
The go.mod file defines the import paths and dependencies. To create this file for your token server, run the following command:
go mod init sampleServerInstall dependencies
To install the dependencies, run the following command:
go getStart the server
To start the server, execute:
go run server.goImportant
This sample server is for development purposes only. It should not be used in a production environment.
Login with a token
To log in using an RTM token, fetch the token from your token server and provide it to the SDK during the login process:
// Fetch a token from your token server
// Log in to Signaling
rtm.login(token) {res, error in
if error != nil {
print("\\(error?.operation) failed! error reason is \\(error?.reason)")
} else {
print("success")
}
}// Fetch a token from your token server
// Log in to Signaling
[rtm loginByToken:@"your_token" completion:^(AgoraRtmCommonResponse * _Nullable response, AgoraRtmErrorInfo * _Nullable errorInfo) {
if (errorInfo == nil) {
NSLog(@"login success!!");
} else {
NSLog(@"login failed, errorCode %d, reason %@", errorInfo.errorCode, errorInfo.reason);
}
}];Note
- The user ID and app ID you use to initialize the Signaling client instance must be the same as the user ID and app ID you use on the token server to generate a token.
- When integrating the Signaling SDK into your app, ensure that the app certificate is properly configured in Agora Console. The app certificate serves as a key authentication mechanism between your app and Agora SDRTN® to ensure secure and reliable communication.
Join a stream channel using a token
To join a stream channel using a token, fetch the token from your token server and provide it to the SDK during the join process. For details, refer to the API reference.
Token expiration and renewal
You configure the validity period of an RTM token in your token generator according to your business needs. The maximum validity period of a token is 24 hours. When an RTM token is about to expire, the tokenPrivilegeWillExpire callback is triggered 30 seconds before the expiration time. When you receive this callback, retrieve a fresh RTM token from your token server, and call renewToken to pass the new token to the SDK.
If the token expires, the SDK triggers an didReceiveLinkStateEvent callback and reports the following information:
currentState:.failedoperation:.serverRejectreason:.tokenExpired
currentState:AgoraRtmLinkStateFailedoperation:AgoraRtmLinkOperationServerRejectedreason:AgoraRtmLinkStateReasonTokenExpired
In this case, use the logout method to log out of Signaling, retrieve a fresh token, and then log in again.
An alternative approach to handling token expiration through the tokenPrivilegeWillExpire and didReceiveLinkStateEvent callbacks is to handle expiration proactively. Best practice is to update the token periodically to ensure seamless authentication and uninterrupted operation.
Reference
This section contains content that completes the information on this page, or points you to documentation that explains other aspects to this product.
BuildToken API reference
This section explains the API parameters and descriptions for generating AccessToken2 using Golang as an example:
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()
}| Parameter | Description |
|---|---|
appId | The app ID generated when you create a project in Agora Console. |
appCertificate | Your app certificate. |
userId | The user ID, used to identify a user or device. To differentiate between users and devices, ensure that the userId is globally unique and remains unchanged for the lifetime of the user or device. |
expire | The validity period of the token (in seconds). The maximum validity period is 24 hours. |
Authentication is the act of validating the identity of a user before they access a system. Agora uses digital tokens to authenticate users and their privileges before they access Signaling. A token is a string used to verify user privileges when logging in or joining a channel. When a user connects to Agora and passes in the token, the server verifies the user's identity and permissions based on the information in the token.
This page shows you how to set up a token server, and use it to connect securely to Signaling.
Understand the tech
Signaling provides two types of channels:
- Message channels: To join a message channel, you only need to use an RTM token when calling the login method. An RTM token is valid only for the user Id that you use to generate it.
- Stream channels: To join a stream channel, you use an RTC token when calling the join method. An RTC token is valid only for the channel name and the user Id that you used to generate it.
The following figure shows the call flow you implement to create step-up-authentication with Signaling:
Authentication workflow
To log in to Signaling, your app retrieves an RTM token from the token server in your security infrastructure. Your app then sends this token to Agora SDRTN® for authentication. Agora SDRTN® validates the token and reads the user and project information stored in the token. To join a stream channel you request an RTC token from the server by supplying a user Id and a channel name. You do not need an authentication token to subscribe to a message channel.
A token contains the following information:
- The App ID of your Agora project
- The user Id of the user to be authenticated
- The stream channel name (RTC token only)
- The Unix timestamp indicating when the token will expire
Prerequisites
Ensure that you have:
-
Integrated the Signaling SDK in your project, and implemented the framework functionality from the SDK quickstart page.
-
The following information from Agora Console:
- App ID: A unique string provided by Agora that identifies your project.
- App certificate: A string generated using Agora Console to enable token authentication. To obtain the App certificate for your project, enable primary certificate.
Implement basic authentication
In the SDK quickstart, the app uses an authentication token obtained from Agora Console to join a channel. In a production environment, your app retrieves this token from a token server.
Token generation code
Agora provides an open source token generator code repository on GitHub. The repository contains code samples, based on the HMAC-SHA256 algorithm, in the following languages to generate tokens on your own server:
| Language | Core method | Sample code |
|---|---|---|
| Go | buildToken | sample.go |
| PHP | buildToken | RtmTokenBuilder2Sample.php |
| Python 2 | buildToken | RtmTokenBuilder2Sample.py |
| Python 3 | buildToken | RtmTokenBuilder2Sample.py |
| C++ | buildToken | RtmTokenBuilder2Sample.cpp |
| Java | buildToken | RtmTokenBuilder2Sample.java |
Generate a token
This section shows you how to generate an RTM token using Go language AccessToken2 code from the GitHub repository. To use another language refer to the code samples and READMEs in the Github repository. To generate an RTC token refer to Secure authentication with tokens.
Before proceeding, make sure that you have:
- Installed Go 1.14 or above
- If you are using a Go version lower than 1.16, set the
GO111MODULEenvironment variable toon.
Take the following steps to set up a token generation server:
Create server.go
Create a server.go file containing the following code. Replace Your_App_ID and Your_App_Certificate with your app ID and app certificate from Agora Console.
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
// Use RtmTokenBuilder to generate an RTM Token
func generateRtmToken(rtm_uid string){
appID := "Your_App_ID"
appCertificate := "Your_App_Certificate"
// Token expiration time in seconds
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(){
// Use an int type uid to generate an 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)
}
}Refer to the BuildToken API reference for parameter descriptions.
Create go.mod
The go.mod file defines the import paths and dependencies. To create this file for your token server, run the following command:
go mod init sampleServerInstall dependencies
To install the dependencies, run the following command:
go getStart the server
To start the server, execute:
go run server.goImportant
This sample server is for development purposes only. It should not be used in a production environment.
Login with a token
To log in using an RTM token, fetch the token from your token server and provide it to the SDK during the login process:
// Fetch a token from your token server
// Log in to Signaling
rtm.login(token) {res, error in
if error != nil {
print("\\(error?.operation) failed! error reason is \\(error?.reason)")
} else {
print("success")
}
}// Fetch a token from your token server
// Log in to Signaling
[rtm loginByToken:@"your_token" completion:^(AgoraRtmCommonResponse * _Nullable response, AgoraRtmErrorInfo * _Nullable errorInfo) {
if (errorInfo == nil) {
NSLog(@"login success!!");
} else {
NSLog(@"login failed, errorCode %d, reason %@", errorInfo.errorCode, errorInfo.reason);
}
}];Note
- The user ID and app ID you use to initialize the Signaling client instance must be the same as the user ID and app ID you use on the token server to generate a token.
- When integrating the Signaling SDK into your app, ensure that the app certificate is properly configured in Agora Console. The app certificate serves as a key authentication mechanism between your app and Agora SDRTN® to ensure secure and reliable communication.
Join a stream channel using a token
To join a stream channel using a token, fetch the token from your token server and provide it to the SDK during the join process. For details, refer to the API reference.
Token expiration and renewal
You configure the validity period of an RTM token in your token generator according to your business needs. The maximum validity period of a token is 24 hours. When an RTM token is about to expire, the tokenPrivilegeWillExpire callback is triggered 30 seconds before the expiration time. When you receive this callback, retrieve a fresh RTM token from your token server, and call renewToken to pass the new token to the SDK.
If the token expires, the SDK triggers an didReceiveLinkStateEvent callback and reports the following information:
currentState:.failedoperation:.serverRejectreason:.tokenExpired
currentState:AgoraRtmLinkStateFailedoperation:AgoraRtmLinkOperationServerRejectedreason:AgoraRtmLinkStateReasonTokenExpired
In this case, use the logout method to log out of Signaling, retrieve a fresh token, and then log in again.
An alternative approach to handling token expiration through the tokenPrivilegeWillExpire and didReceiveLinkStateEvent callbacks is to handle expiration proactively. Best practice is to update the token periodically to ensure seamless authentication and uninterrupted operation.
Reference
This section contains content that completes the information on this page, or points you to documentation that explains other aspects to this product.
BuildToken API reference
This section explains the API parameters and descriptions for generating AccessToken2 using Golang as an example:
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()
}| Parameter | Description |
|---|---|
appId | The app ID generated when you create a project in Agora Console. |
appCertificate | Your app certificate. |
userId | The user ID, used to identify a user or device. To differentiate between users and devices, ensure that the userId is globally unique and remains unchanged for the lifetime of the user or device. |
expire | The validity period of the token (in seconds). The maximum validity period is 24 hours. |
Authentication is the act of validating the identity of a user before they access a system. Agora uses digital tokens to authenticate users and their privileges before they access Signaling. A token is a string used to verify user privileges when logging in or joining a channel. When a user connects to Agora and passes in the token, the server verifies the user's identity and permissions based on the information in the token.
This page shows you how to set up a token server, and use it to connect securely to Signaling.
Understand the tech
Signaling provides two types of channels:
- Message channels: To join a message channel, you only need to use an RTM token when calling the login method. An RTM token is valid only for the user Id that you use to generate it.
- Stream channels: To join a stream channel, you use an RTC token when calling the join method. An RTC token is valid only for the channel name and the user Id that you used to generate it.
The following figure shows the call flow you implement to create step-up-authentication with Signaling:
Authentication workflow
To log in to Signaling, your app retrieves an RTM token from the token server in your security infrastructure. Your app then sends this token to Agora SDRTN® for authentication. Agora SDRTN® validates the token and reads the user and project information stored in the token. To join a stream channel you request an RTC token from the server by supplying a user Id and a channel name. You do not need an authentication token to subscribe to a message channel.
A token contains the following information:
- The App ID of your Agora project
- The user Id of the user to be authenticated
- The stream channel name (RTC token only)
- The Unix timestamp indicating when the token will expire
Prerequisites
Ensure that you have:
-
Integrated the Signaling SDK in your project, and implemented the framework functionality from the SDK quickstart page.
-
The following information from Agora Console:
- App ID: A unique string provided by Agora that identifies your project.
- App certificate: A string generated using Agora Console to enable token authentication. To obtain the App certificate for your project, enable primary certificate.
Implement basic authentication
In the SDK quickstart, the app uses an authentication token obtained from Agora Console to join a channel. In a production environment, your app retrieves this token from a token server.
Token generation code
Agora provides an open source token generator code repository on GitHub. The repository contains code samples, based on the HMAC-SHA256 algorithm, in the following languages to generate tokens on your own server:
| Language | Core method | Sample code |
|---|---|---|
| Go | buildToken | sample.go |
| PHP | buildToken | RtmTokenBuilder2Sample.php |
| Python 2 | buildToken | RtmTokenBuilder2Sample.py |
| Python 3 | buildToken | RtmTokenBuilder2Sample.py |
| C++ | buildToken | RtmTokenBuilder2Sample.cpp |
| Java | buildToken | RtmTokenBuilder2Sample.java |
Generate a token
This section shows you how to generate an RTM token using Go language AccessToken2 code from the GitHub repository. To use another language refer to the code samples and READMEs in the Github repository. To generate an RTC token refer to Secure authentication with tokens.
Before proceeding, make sure that you have:
- Installed Go 1.14 or above
- If you are using a Go version lower than 1.16, set the
GO111MODULEenvironment variable toon.
Take the following steps to set up a token generation server:
Create server.go
Create a server.go file containing the following code. Replace Your_App_ID and Your_App_Certificate with your app ID and app certificate from Agora Console.
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
// Use RtmTokenBuilder to generate an RTM Token
func generateRtmToken(rtm_uid string){
appID := "Your_App_ID"
appCertificate := "Your_App_Certificate"
// Token expiration time in seconds
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(){
// Use an int type uid to generate an 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)
}
}Refer to the BuildToken API reference for parameter descriptions.
Create go.mod
The go.mod file defines the import paths and dependencies. To create this file for your token server, run the following command:
go mod init sampleServerInstall dependencies
To install the dependencies, run the following command:
go getStart the server
To start the server, execute:
go run server.goImportant
This sample server is for development purposes only. It should not be used in a production environment.
Login with a token
To log in to Signaling using an RTM token, fetch a token from your token server and pass it to the SDK by calling login:
class TokenResult {
final String status;
final String token;
TokenResult(this.status, this.token);
}
// Define the function to fetch a token from your token server
Future<TokenResult> fetchToken({required String channelName}) async {
// Request token from a token server
// TODO: Add code here to get a token
String status = "success";
String token = "your_token_here";
return TokenResult(status, token);
}
// Log in to Signaling
var tokenResult = await fetchToken(channelName: '');
var (status, response) = await rtmClient.login(tokenResult.token);
if (status.error == true) {
print(status);
} else {
print(response);
}Note
- The user ID and app ID you use to initialize the Signaling client instance must be the same as the user ID and app ID you use on the token server to generate a token.
- When integrating the Signaling SDK into your app, ensure that the app certificate is properly configured. The app certificate serves as a key authentication mechanism between your app and Agora SDRTN® to ensure secure and reliable communication.
Join a stream channel using a token
To join a stream channel using a token, fetch an RTC token from your token server and pass it to the SDK when you call join. For details, refer to the API reference.
Token expiration and renewal
You configure the validity period of an RTM token in your token generator according to your business needs. The maximum validity period of a token is 24 hours. When an RTM token is about to expire, the token callback is triggered 30 seconds before the expiration time. When you receive this callback, retrieve a fresh token from your token server, and call renewToken to pass the new token to the SDK.
rtmClient.addListener({
token: (event) async {
if (event.channelName == '') {
// An empty channelName indicates that the MESSAGE service token has expired
// Fetch the MESSAGE service (RTM) token
var result = await fetchToken();
rtmClient.renewToken(result.token); // Update the MESSAGE service token
} else { // The `STREAM` service token has expired
// Fetch the `STREAM` service (RTC) token
var result = await fetchToken(channelName: event.channelName);
// Update the `STREAM` service token
streamChannel.renewToken(result.token);
}
}
});If the token expires, the SDK triggers an onLinkStateEvent callback and reports the following information:
currentState:failedoperation:serverRejectreason:Ticket expired
In this case, log out of Signaling using the logout method, retrieve a fresh token, and login again.
An alternative approach to handling token expiration through the token and onLinkStateEvent callbacks is to handle expiration proactively. Best practice is to update the token periodically to ensure seamless authentication and uninterrupted operation.
Reference
This section contains content that completes the information on this page, or points you to documentation that explains other aspects to this product.
BuildToken API reference
This section explains the API parameters and descriptions for generating AccessToken2 using Golang as an example:
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()
}| Parameter | Description |
|---|---|
appId | The app ID generated when you create a project in Agora Console. |
appCertificate | Your app certificate. |
userId | The user ID, used to identify a user or device. To differentiate between users and devices, ensure that the userId is globally unique and remains unchanged for the lifetime of the user or device. |
expire | The validity period of the token (in seconds). The maximum validity period is 24 hours. |
Authentication is the act of validating the identity of a user before they access a system. Agora uses digital tokens to authenticate users and their privileges before they access Signaling. A token is a string used to verify user privileges when logging in or joining a channel. When a user connects to Agora and passes in the token, the server verifies the user's identity and permissions based on the information in the token.
This page shows you how to set up a token server, and use it to connect securely to Signaling.
Understand the tech
Signaling provides two types of channels:
- Message channels: To join a message channel, you only need to use an RTM token when calling the login method. An RTM token is valid only for the user Id that you use to generate it.
- Stream channels: To join a stream channel, you use an RTC token when calling the join method. An RTC token is valid only for the channel name and the user Id that you used to generate it.
The following figure shows the call flow you implement to create step-up-authentication with Signaling:
Authentication workflow
To log in to Signaling, your app retrieves an RTM token from the token server in your security infrastructure. Your app then sends this token to Agora SDRTN® for authentication. Agora SDRTN® validates the token and reads the user and project information stored in the token. To join a stream channel you request an RTC token from the server by supplying a user Id and a channel name. You do not need an authentication token to subscribe to a message channel.
A token contains the following information:
- The App ID of your Agora project
- The user Id of the user to be authenticated
- The stream channel name (RTC token only)
- The Unix timestamp indicating when the token will expire
Prerequisites
Ensure that you have:
-
Integrated the Signaling SDK in your project, and implemented the framework functionality from the SDK quickstart page.
-
The following information from Agora Console:
- App ID: A unique string provided by Agora that identifies your project.
- App certificate: A string generated using Agora Console to enable token authentication. To obtain the App certificate for your project, enable primary certificate.
Implement basic authentication
In the SDK quickstart, the app uses an authentication token obtained from Agora Console to join a channel. In a production environment, your app retrieves this token from a token server.
Token generation code
Agora provides an open source token generator code repository on GitHub. The repository contains code samples, based on the HMAC-SHA256 algorithm, in the following languages to generate tokens on your own server:
| Language | Core method | Sample code |
|---|---|---|
| Go | buildToken | sample.go |
| PHP | buildToken | RtmTokenBuilder2Sample.php |
| Python 2 | buildToken | RtmTokenBuilder2Sample.py |
| Python 3 | buildToken | RtmTokenBuilder2Sample.py |
| C++ | buildToken | RtmTokenBuilder2Sample.cpp |
| Java | buildToken | RtmTokenBuilder2Sample.java |
Generate a token
This section shows you how to generate an RTM token using Go language AccessToken2 code from the GitHub repository. To use another language refer to the code samples and READMEs in the Github repository. To generate an RTC token refer to Secure authentication with tokens.
Before proceeding, make sure that you have:
- Installed Go 1.14 or above
- If you are using a Go version lower than 1.16, set the
GO111MODULEenvironment variable toon.
Take the following steps to set up a token generation server:
Create server.go
Create a server.go file containing the following code. Replace Your_App_ID and Your_App_Certificate with your app ID and app certificate from Agora Console.
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
// Use RtmTokenBuilder to generate an RTM Token
func generateRtmToken(rtm_uid string){
appID := "Your_App_ID"
appCertificate := "Your_App_Certificate"
// Token expiration time in seconds
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(){
// Use an int type uid to generate an 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)
}
}Refer to the BuildToken API reference for parameter descriptions.
Create go.mod
The go.mod file defines the import paths and dependencies. To create this file for your token server, run the following command:
go mod init sampleServerInstall dependencies
To install the dependencies, run the following command:
go getStart the server
To start the server, execute:
go run server.goImportant
This sample server is for development purposes only. It should not be used in a production environment.
Reference
This section contains content that completes the information on this page, or points you to documentation that explains other aspects to this product.
BuildToken API reference
This section explains the API parameters and descriptions for generating AccessToken2 using Golang as an example:
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()
}| Parameter | Description |
|---|---|
appId | The app ID generated when you create a project in Agora Console. |
appCertificate | Your app certificate. |
userId | The user ID, used to identify a user or device. To differentiate between users and devices, ensure that the userId is globally unique and remains unchanged for the lifetime of the user or device. |
expire | The validity period of the token (in seconds). The maximum validity period is 24 hours. |
Authentication is the act of validating the identity of a user before they access a system. Agora uses digital tokens to authenticate users and their privileges before they access Signaling. A token is a string used to verify user privileges when logging in or joining a channel. When a user connects to Agora and passes in the token, the server verifies the user's identity and permissions based on the information in the token.
This page shows you how to set up a token server, and use it to connect securely to Signaling.
Understand the tech
Signaling provides two types of channels:
- Message channels: To join a message channel, you only need to use an RTM token when calling the login method. An RTM token is valid only for the user Id that you use to generate it.
- Stream channels: To join a stream channel, you use an RTC token when calling the join method. An RTC token is valid only for the channel name and the user Id that you used to generate it.
The following figure shows the call flow you implement to create step-up-authentication with Signaling:
Authentication workflow
To log in to Signaling, your app retrieves an RTM token from the token server in your security infrastructure. Your app then sends this token to Agora SDRTN® for authentication. Agora SDRTN® validates the token and reads the user and project information stored in the token. To join a stream channel you request an RTC token from the server by supplying a user Id and a channel name. You do not need an authentication token to subscribe to a message channel.
A token contains the following information:
- The App ID of your Agora project
- The user Id of the user to be authenticated
- The stream channel name (RTC token only)
- The Unix timestamp indicating when the token will expire
Prerequisites
Ensure that you have:
-
Integrated the Signaling SDK in your project, and implemented the framework functionality from the SDK quickstart page.
-
The following information from Agora Console:
- App ID: A unique string provided by Agora that identifies your project.
- App certificate: A string generated using Agora Console to enable token authentication. To obtain the App certificate for your project, enable primary certificate.
Implement basic authentication
In the SDK quickstart, the app uses an authentication token obtained from Agora Console to join a channel. In a production environment, your app retrieves this token from a token server.
Token generation code
Agora provides an open source token generator code repository on GitHub. The repository contains code samples, based on the HMAC-SHA256 algorithm, in the following languages to generate tokens on your own server:
| Language | Core method | Sample code |
|---|---|---|
| Go | buildToken | sample.go |
| PHP | buildToken | RtmTokenBuilder2Sample.php |
| Python 2 | buildToken | RtmTokenBuilder2Sample.py |
| Python 3 | buildToken | RtmTokenBuilder2Sample.py |
| C++ | buildToken | RtmTokenBuilder2Sample.cpp |
| Java | buildToken | RtmTokenBuilder2Sample.java |
Generate a token
This section shows you how to generate an RTM token using Go language AccessToken2 code from the GitHub repository. To use another language refer to the code samples and READMEs in the Github repository. To generate an RTC token refer to Secure authentication with tokens.
Before proceeding, make sure that you have:
- Installed Go 1.14 or above
- If you are using a Go version lower than 1.16, set the
GO111MODULEenvironment variable toon.
Take the following steps to set up a token generation server:
Create server.go
Create a server.go file containing the following code. Replace Your_App_ID and Your_App_Certificate with your app ID and app certificate from Agora Console.
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
// Use RtmTokenBuilder to generate an RTM Token
func generateRtmToken(rtm_uid string){
appID := "Your_App_ID"
appCertificate := "Your_App_Certificate"
// Token expiration time in seconds
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(){
// Use an int type uid to generate an 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)
}
}Refer to the BuildToken API reference for parameter descriptions.
Create go.mod
The go.mod file defines the import paths and dependencies. To create this file for your token server, run the following command:
go mod init sampleServerInstall dependencies
To install the dependencies, run the following command:
go getStart the server
To start the server, execute:
go run server.goImportant
This sample server is for development purposes only. It should not be used in a production environment.
Login with a token
To log in to Signaling using an RTM token, fetch a token from your token server and pass it to the SDK by calling login:
// Fetch a token from your token server
// ...
// Log in to Signaling
RtmConfig config;
config.appId = "your app id";
config.userId = "your user id";
config.eventHandler = new RtmEventHandler();
int errorCode = 0;
IRtmClient* rtmClient = createAgoraRtmClient(config, errorCode);
if (!rtmClient || errorCode != 0) {
// create rtm client failed
}
uint64_t requestId;
rtmClient->login("your token", requestId);Note
- The user ID and app ID you use to initialize the Signaling client instance must be the same as the user ID and app ID you use on the token server to generate a token.
- When integrating the Signaling SDK into your app, ensure that the app certificate is properly configured. The app certificate serves as a key authentication mechanism between your app and Agora SDRTN® to ensure secure and reliable communication.
Join a stream channel using a token
To join a stream channel using a token, fetch an RTC token from your token server and pass it to the SDK when you call join. For details, refer to the API reference.
Token expiration and renewal
You configure the validity period of an RTM token in your token generator according to your business needs. The maximum validity period of a token is 24 hours. When an RTM token is about to expire, the onTokenPrivilegeWillExpire callback is triggered 30 seconds before the expiration time. When you receive this callback, retrieve a fresh RTM token from your token server, and call renewToken to pass the new token to the SDK.
If the token expires, the SDK triggers an onLinkStateEvent callback and reports the following information:
currentState:RTM_LINK_STATE_FAILEDoperation:RTM_LINK_OPERATION_SERVER_REJECTreason:Ticket expired
In this case, log out of Signaling using the logout method, retrieve a fresh token, and login again.
An alternative approach to handling token expiration through the onTokenPrivilegeWillExpire and onLinkStateEvent callbacks is to handle expiration proactively. Best practice is to update the token periodically to ensure seamless authentication and uninterrupted operation.
Reference
This section contains content that completes the information on this page, or points you to documentation that explains other aspects to this product.
BuildToken API reference
This section explains the API parameters and descriptions for generating AccessToken2 using Golang as an example:
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()
}| Parameter | Description |
|---|---|
appId | The app ID generated when you create a project in Agora Console. |
appCertificate | Your app certificate. |
userId | The user ID, used to identify a user or device. To differentiate between users and devices, ensure that the userId is globally unique and remains unchanged for the lifetime of the user or device. |
expire | The validity period of the token (in seconds). The maximum validity period is 24 hours. |
Authentication is the act of validating the identity of a user before they access a system. Agora uses digital tokens to authenticate users and their privileges before they access Signaling. A token is a string used to verify user privileges when logging in or joining a channel. When a user connects to Agora and passes in the token, the server verifies the user's identity and permissions based on the information in the token.
This page shows you how to set up a token server, and use it to connect securely to Signaling.
Understand the tech
Signaling provides two types of channels:
- Message channels: To join a message channel, you only need to use an RTM token when calling the login method. An RTM token is valid only for the user Id that you use to generate it.
- Stream channels: To join a stream channel, you use an RTC token when calling the join method. An RTC token is valid only for the channel name and the user Id that you used to generate it.
The following figure shows the call flow you implement to create step-up-authentication with Signaling:
Authentication workflow
To log in to Signaling, your app retrieves an RTM token from the token server in your security infrastructure. Your app then sends this token to Agora SDRTN® for authentication. Agora SDRTN® validates the token and reads the user and project information stored in the token. To join a stream channel you request an RTC token from the server by supplying a user Id and a channel name. You do not need an authentication token to subscribe to a message channel.
A token contains the following information:
- The App ID of your Agora project
- The user Id of the user to be authenticated
- The stream channel name (RTC token only)
- The Unix timestamp indicating when the token will expire
Prerequisites
Ensure that you have:
-
Integrated the Signaling SDK in your project, and implemented the framework functionality from the SDK quickstart page.
-
The following information from Agora Console:
- App ID: A unique string provided by Agora that identifies your project.
- App certificate: A string generated using Agora Console to enable token authentication. To obtain the App certificate for your project, enable primary certificate.
Implement basic authentication
In the SDK quickstart, the app uses an authentication token obtained from Agora Console to join a channel. In a production environment, your app retrieves this token from a token server.
Token generation code
Agora provides an open source token generator code repository on GitHub. The repository contains code samples, based on the HMAC-SHA256 algorithm, in the following languages to generate tokens on your own server:
| Language | Core method | Sample code |
|---|---|---|
| Go | buildToken | sample.go |
| PHP | buildToken | RtmTokenBuilder2Sample.php |
| Python 2 | buildToken | RtmTokenBuilder2Sample.py |
| Python 3 | buildToken | RtmTokenBuilder2Sample.py |
| C++ | buildToken | RtmTokenBuilder2Sample.cpp |
| Java | buildToken | RtmTokenBuilder2Sample.java |
Generate a token
This section shows you how to generate an RTM token using Go language AccessToken2 code from the GitHub repository. To use another language refer to the code samples and READMEs in the Github repository. To generate an RTC token refer to Secure authentication with tokens.
Before proceeding, make sure that you have:
- Installed Go 1.14 or above
- If you are using a Go version lower than 1.16, set the
GO111MODULEenvironment variable toon.
Take the following steps to set up a token generation server:
Create server.go
Create a server.go file containing the following code. Replace Your_App_ID and Your_App_Certificate with your app ID and app certificate from Agora Console.
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
// Use RtmTokenBuilder to generate an RTM Token
func generateRtmToken(rtm_uid string){
appID := "Your_App_ID"
appCertificate := "Your_App_Certificate"
// Token expiration time in seconds
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(){
// Use an int type uid to generate an 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)
}
}Refer to the BuildToken API reference for parameter descriptions.
Create go.mod
The go.mod file defines the import paths and dependencies. To create this file for your token server, run the following command:
go mod init sampleServerInstall dependencies
To install the dependencies, run the following command:
go getStart the server
To start the server, execute:
go run server.goImportant
This sample server is for development purposes only. It should not be used in a production environment.
Login with a token
To log in to Signaling using an RTM token, fetch a token from your token server and pass it to the SDK by calling login:
// Fetch a token from your token server
// ...
// Log in to Signaling
RtmConfig config;
config.appId = "your app id";
config.userId = "your user id";
config.eventHandler = new RtmEventHandler();
int errorCode = 0;
IRtmClient* rtmClient = createAgoraRtmClient(config, errorCode);
if (!rtmClient || errorCode != 0) {
// create rtm client failed
}
uint64_t requestId;
rtmClient->login("your token", requestId);Note
- The user ID and app ID you use to initialize the Signaling client instance must be the same as the user ID and app ID you use on the token server to generate a token.
- When integrating the Signaling SDK into your app, ensure that the app certificate is properly configured. The app certificate serves as a key authentication mechanism between your app and Agora SDRTN® to ensure secure and reliable communication.
Join a stream channel using a token
To join a stream channel using a token, fetch an RTC token from your token server and pass it to the SDK when you call join. For details, refer to the API reference.
Token expiration and renewal
You configure the validity period of an RTM token in your token generator according to your business needs. The maximum validity period of a token is 24 hours. When an RTM token is about to expire, the onTokenPrivilegeWillExpire callback is triggered 30 seconds before the expiration time. When you receive this callback, retrieve a fresh RTM token from your token server, and call renewToken to pass the new token to the SDK.
If the token expires, the SDK triggers an onLinkStateEvent callback and reports the following information:
currentState:RTM_LINK_STATE_FAILEDoperation:RTM_LINK_OPERATION_SERVER_REJECTreason:Ticket expired
In this case, log out of Signaling using the logout method, retrieve a fresh token, and login again.
An alternative approach to handling token expiration through the onTokenPrivilegeWillExpire and onLinkStateEvent callbacks is to handle expiration proactively. Best practice is to update the token periodically to ensure seamless authentication and uninterrupted operation.
Reference
This section contains content that completes the information on this page, or points you to documentation that explains other aspects to this product.
BuildToken API reference
This section explains the API parameters and descriptions for generating AccessToken2 using Golang as an example:
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()
}| Parameter | Description |
|---|---|
appId | The app ID generated when you create a project in Agora Console. |
appCertificate | Your app certificate. |
userId | The user ID, used to identify a user or device. To differentiate between users and devices, ensure that the userId is globally unique and remains unchanged for the lifetime of the user or device. |
expire | The validity period of the token (in seconds). The maximum validity period is 24 hours. |
Authentication is the act of validating the identity of a user before they access a system. Agora uses digital tokens to authenticate users and their privileges before they access Signaling. A token is a string used to verify user privileges when logging in or joining a channel. When a user connects to Agora and passes in the token, the server verifies the user's identity and permissions based on the information in the token.
This page shows you how to set up a token server, and use it to connect securely to Signaling.
Understand the tech
Signaling provides two types of channels:
- Message channels: To join a message channel, you only need to use an RTM token when calling the login method. An RTM token is valid only for the user Id that you use to generate it.
- Stream channels: To join a stream channel, you use an RTC token when calling the join method. An RTC token is valid only for the channel name and the user Id that you used to generate it.
The following figure shows the call flow you implement to create step-up-authentication with Signaling:
Authentication workflow
To log in to Signaling, your app retrieves an RTM token from the token server in your security infrastructure. Your app then sends this token to Agora SDRTN® for authentication. Agora SDRTN® validates the token and reads the user and project information stored in the token. To join a stream channel you request an RTC token from the server by supplying a user Id and a channel name. You do not need an authentication token to subscribe to a message channel.
A token contains the following information:
- The App ID of your Agora project
- The user Id of the user to be authenticated
- The stream channel name (RTC token only)
- The Unix timestamp indicating when the token will expire
Prerequisites
Ensure that you have:
-
Integrated the Signaling SDK in your project, and implemented the framework functionality from the SDK quickstart page.
-
The following information from Agora Console:
- App ID: A unique string provided by Agora that identifies your project.
- App certificate: A string generated using Agora Console to enable token authentication. To obtain the App certificate for your project, enable primary certificate.
Implement basic authentication
In the SDK quickstart, the app uses an authentication token obtained from Agora Console to join a channel. In a production environment, your app retrieves this token from a token server.
Token generation code
Agora provides an open source token generator code repository on GitHub. The repository contains code samples, based on the HMAC-SHA256 algorithm, in the following languages to generate tokens on your own server:
| Language | Core method | Sample code |
|---|---|---|
| Go | buildToken | sample.go |
| PHP | buildToken | RtmTokenBuilder2Sample.php |
| Python 2 | buildToken | RtmTokenBuilder2Sample.py |
| Python 3 | buildToken | RtmTokenBuilder2Sample.py |
| C++ | buildToken | RtmTokenBuilder2Sample.cpp |
| Java | buildToken | RtmTokenBuilder2Sample.java |
Generate a token
This section shows you how to generate an RTM token using Go language AccessToken2 code from the GitHub repository. To use another language refer to the code samples and READMEs in the Github repository. To generate an RTC token refer to Secure authentication with tokens.
Before proceeding, make sure that you have:
- Installed Go 1.14 or above
- If you are using a Go version lower than 1.16, set the
GO111MODULEenvironment variable toon.
Take the following steps to set up a token generation server:
Create server.go
Create a server.go file containing the following code. Replace Your_App_ID and Your_App_Certificate with your app ID and app certificate from Agora Console.
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
// Use RtmTokenBuilder to generate an RTM Token
func generateRtmToken(rtm_uid string){
appID := "Your_App_ID"
appCertificate := "Your_App_Certificate"
// Token expiration time in seconds
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(){
// Use an int type uid to generate an 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)
}
}Refer to the BuildToken API reference for parameter descriptions.
Create go.mod
The go.mod file defines the import paths and dependencies. To create this file for your token server, run the following command:
go mod init sampleServerInstall dependencies
To install the dependencies, run the following command:
go getStart the server
To start the server, execute:
go run server.goImportant
This sample server is for development purposes only. It should not be used in a production environment.
Login with a token
To log in to Signaling using an RTM token, fetch a token from your token server and pass it to the SDK by calling LoginAsync:
// Fetch a token from your token server
// Log in to Signaling
var result = await rtmClient.LoginAsync("your_token");
if (result.Status.Error)
{
// Failed to log in, handle the error
Debug.Log(result.Status.ErrorCode);
}
else
{
// Login successful
}Note
- The user ID and app ID you use to initialize the Signaling client instance must be the same as the user ID and app ID you use on the token server to generate a token.
- When integrating the Signaling SDK into your app, ensure that the app certificate is properly configured. The app certificate serves as a key authentication mechanism between your app and Agora SDRTN® to ensure secure and reliable communication.
Join a stream channel using a token
To join a stream channel using a token, fetch an RTC token from your token server and pass it to the SDK when you call JoinAsync. For details, refer to the API reference.
Token expiration and renewal
You configure the validity period of an RTM token in your token generator according to your business needs. The maximum validity period of a token is 24 hours. When an RTM token is about to expire, the OnTokenPrivilegeWillExpire callback is triggered 30 seconds before the expiration time. When you receive this callback, retrieve a fresh RTM token from your token server, and call renewToken to pass the new token to the SDK.
If the token expires, the SDK triggers an OnConnectionStateChanged callback indicating a change in connection status to FAILED with the reason TOKEN_EXPIRED.
In this case, log out of Signaling using the LogoutAsync method, retrieve a fresh token, and LoginAsync again.
An alternative approach to handling token expiration through the OnTokenPrivilegeWillExpire and OnConnectionStateChanged callbacks is to handle expiration proactively. Best practice is to update the token periodically to ensure seamless authentication and uninterrupted operation.
Reference
This section contains content that completes the information on this page, or points you to documentation that explains other aspects to this product.
BuildToken API reference
This section explains the API parameters and descriptions for generating AccessToken2 using Golang as an example:
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()
}| Parameter | Description |
|---|---|
appId | The app ID generated when you create a project in Agora Console. |
appCertificate | Your app certificate. |
userId | The user ID, used to identify a user or device. To differentiate between users and devices, ensure that the userId is globally unique and remains unchanged for the lifetime of the user or device. |
expire | The validity period of the token (in seconds). The maximum validity period is 24 hours. |
