Skip to main content
Android
iOS
Web
Windows
Unity
Flutter
React Native

Secure authentication with tokens

Agora uses digital tokens to authenticate users and their privileges before they access Agora Chat. For test purposes, you can generate temporary tokens in Agora Console. See Manage users and generate tokens for details.

In a development environment, you deploy your own app server to generate authentication tokens. This page introduces how to set up a token server, retrieve tokens from your server, and authenticate your users.

Understand the tech

Agora Chat employs two types of tokens for authentication:

  • Use tokens with app privileges to call Agora RESTful APIs.

  • Use tokens with user privileges for user authentication and interaction through the Agora Chat SDK.

Use-caseToken typeInformation required to generateMaximum validity
RESTful API callsToken with app privileges
  • App ID of your Agora Chat project
  • App certificate of your Agora Chat project
  • Token validity period for your Agora Chat project
24 hours
SDK API callsToken with user privileges
  • App ID of your Agora Chat project
  • App certificate of your Agora Chat project
  • Token validity period for your Agora Chat project
  • The Agora Chat user ID
24 hours

Prerequisites

In order to follow this procedure, you must have the following:

If you have a firewall implemented in your network environment, Agora provides a firewall whitelist solution for you to access Agora Chat in environments with restricted network access. If you want to use the firewall whitelist solution, submit a ticket and our technical support will provide the target domain and corresponding IP.

Implement the authentication flow

This section shows you how to supply and consume a token used to authenticate a user with Agora Chat.

Deploy an app server to generate tokens

Tokens used for connecting with Agora Chat are generated by your app server. When a client sends a request, the app server generates an appropriate token. The following figure shows how to manage tokens with app and user privileges to facilitate secure user authentication and interaction with Agora Chat services.

Token generation API call sequence

token_generate_user_token

This section guides you through setting up a token server. Choose your preferred language and follow the step-by-step procedure.

caution

This sample server code provided in this guide is for demonstration purposes only. Do not use it directly in a production environment.

  1. Create and initialize a Go project

    Open your terminal and execute the following commands:

    mkdir chat-token-server
    cd chat-token-server
    go mod init chat-token-server
  2. Add the Agora Tools dependency

    The code uses the chatTokenBuilder library to generate tokens with app and user privileges.

    go get github.com/AgoraIO/Tools/DynamicKey/AgoraDynamicKey/go/src/chatTokenBuilder
  3. Set up the Go HTTP server

    Create a new file server.go, with the following content:

    package mainimport (    "encoding/json"    "fmt"    "log"    "net/http"    "github.com/AgoraIO/Tools/DynamicKey/AgoraDynamicKey/go/src/chatTokenBuilder" )// App credentialsconst (    AppID          = "your_app_id"          // Replace with your actual App ID    AppCertificate = "your_app_certificate" // Replace with your actual App Certificate)type TokenRequest struct {    UserUUID string `json:"user_uuid,omitempty"` // Optional for App Token    Expire   uint32 `json:"expire"`}type TokenResponse struct {    Token string `json:"token"`    Error string `json:"error,omitempty"`}func buildUserTokenHandler(w http.ResponseWriter, r *http.Request) {    var req TokenRequest    if err := json.NewDecoder(r.Body).Decode(&req); err != nil {        http.Error(w, "Invalid request payload", http.StatusBadRequest)        return    }    token, err := chatTokenBuilder.BuildChatUserToken(AppID, AppCertificate, req.UserUUID, req.Expire)    if err != nil {        response := TokenResponse{Error: err.Error()}        json.NewEncoder(w).Encode(response)        return    }    response := TokenResponse{Token: token}    json.NewEncoder(w).Encode(response)}func buildAppTokenHandler(w http.ResponseWriter, r *http.Request) {    var req TokenRequest    if err := json.NewDecoder(r.Body).Decode(&req); err != nil {        http.Error(w, "Invalid request payload", http.StatusBadRequest)        return    }    token, err := chatTokenBuilder.BuildChatAppToken(AppID, AppCertificate, req.Expire)    if err != nil {        response := TokenResponse{Error: err.Error()}        json.NewEncoder(w).Encode(response)        return    }    response := TokenResponse{Token: token}    json.NewEncoder(w).Encode(response)}func main() {    http.HandleFunc("/generate-user-token", buildUserTokenHandler)    http.HandleFunc("/generate-app-token", buildAppTokenHandler)    port := "8080"    fmt.Printf("Starting server on port %s...\n", port)    if err := http.ListenAndServe(":"+port, nil); err != nil {        log.Fatalf("Server failed to start: %v", err)    } }
  4. Run the server

    In server.go, update the values for AppIDd and AppCertificate. Use the following command to run the server:

    go run server.go

    The server will start on http://localhost:8080.

  5. Test the server

    Use the following curl requests to test your server:

    • Generate a user token

      curl -X POST http://localhost:8080/generate-user-token \
      -H "Content-Type: application/json" \
      -d '{"user_uuid": "test_user", "expire": 3600}'
    • Generate an app token

      curl -X POST http://localhost:8080/generate-app-token \
      -H "Content-Type: application/json" \
      -d '{"expire": 3600}'

Chat SDK token authentication

The following code fetches and replaces an expired token for the Agora Chat SDK. It performs the following tasks:

  1. Fetches a fresh token on app startup* At the start of the application, it fetches a valid token for the user from a token server.
  1. Listens for onTokenWillExpire event: The app sets up a listener to monitor when the token is about to expire. Upon receiving this event, it fetches a new token from the token server and renews the token with the Agora Chat SDK.

To execute the code, ensure you set the following values in the code:

  • App Key: The app key of your Agora project.
  • User ID: The username that you will be used communication.
  • Token Server URL: The URL of your token server, which provides valid tokens for authentication.

_157
private String userId = "<User ID of the local user>";
_157
private String token = "<Your authentication token>";
_157
private String appKey = "<App key from Agora console>";
_157
_157
private ChatClient agoraChatClient;
_157
private boolean isJoined = false;
_157
_157
@Override
_157
protected void onCreate(Bundle savedInstanceState) {
_157
super.onCreate(savedInstanceState);
_157
setContentView(R.layout.activity_main);
_157
_157
// Fetch the token from the server when the app starts
_157
fetchAndInitializeToken();
_157
_157
setupChatClient(); // Initialize the ChatClient
_157
setupListeners(); // Add event listeners
_157
}
_157
_157
private void fetchAndInitializeToken() {
_157
// Define the expiration time (1 hour, for example)
_157
int expireSeconds = 3600;
_157
_157
// Fetch the token from the server
_157
String newToken = fetchNewToken(userId, expireSeconds);
_157
_157
if (newToken != null) {
_157
token = newToken;
_157
System.out.println("Token fetched successfully: " + token);
_157
_157
} else {
_157
System.out.println("Failed to fetch token.");
_157
// Handle token fetching failure (e.g., show an error message)
_157
}
_157
}
_157
_157
private void setupChatClient() {
_157
ChatOptions options = new ChatOptions();
_157
if (appKey.isEmpty()) {
_157
showLog("You need to set your AppKey");
_157
return;
_157
}
_157
options.setAppKey(appKey); // Set your app key in options
_157
agoraChatClient = ChatClient.getInstance();
_157
agoraChatClient.init(this, options); // Initialize the ChatClient
_157
agoraChatClient.setDebugMode(true); // Enable debug info output
_157
}
_157
_157
private void setupListeners() {
_157
// Add connection event callbacks
_157
agoraChatClient.addConnectionListener(new ConnectionListener() {
_157
_157
@Override
_157
public void onTokenExpired() {
_157
// The token has expired
_157
System.out.println("Token expired. You need to log in again or fetch a new token.");
_157
// You can handle token expiration here by prompting a user to log in again, or automatically request a new token
_157
}
_157
_157
@Override
_157
public void onTokenWillExpire() {
_157
// The token is about to expire. Get a new token from the token server and renew the token.
_157
System.out.println("Token is about to expire. Fetching a new token...");
_157
_157
// Fetch a new token
_157
int expireSeconds = 3600; // Token expiration time, e.g., 1 hour
_157
_157
// Assuming you have a method to get a new token
_157
String newToken = fetchNewToken(userId, expireSeconds);
_157
_157
if (newToken != null) {
_157
// Renew the token with Agora Chat client
_157
agoraChatClient.renewToken(newToken);
_157
System.out.println("Token renewed successfully.");
_157
} else {
_157
System.out.println("Failed to fetch a new token.");
_157
}
_157
}
_157
});
_157
}
_157
_157
/**
_157
* A method to fetch a new token from the server.
_157
*
_157
* @param userId The userId for which the token is requested.
_157
* @param expireSeconds The expiration time for the token in seconds.
_157
* @return A new token as a String, or null if the request fails.
_157
*/
_157
_157
private String fetchNewToken(String userId, int expireSeconds) {
_157
// Implement the logic to fetch a new token from your token server
_157
// This could be an HTTP call to your server that generates the token
_157
_157
try {
_157
// Example of a basic HTTP request to fetch a new token
_157
String url = "http://localhost:8080/token/generate?userId=" + userId + "&expireSeconds=" + expireSeconds + "&tokenType=user";
_157
_157
// You can use libraries like HttpClient to make the request
_157
// Example using HttpURLConnection
_157
URL tokenUrl = new URL(url);
_157
HttpURLConnection connection = (HttpURLConnection) tokenUrl.openConnection();
_157
connection.setRequestMethod("POST");
_157
connection.setRequestProperty("Content-Type", "application/x-www-form-urlencoded");
_157
_157
// Read response
_157
BufferedReader reader = new BufferedReader(new InputStreamReader(connection.getInputStream()));
_157
StringBuilder response = new StringBuilder();
_157
String line;
_157
while ((line = reader.readLine()) != null) {
_157
response.append(line);
_157
}
_157
reader.close();
_157
_157
// Assuming the response contains the new token
_157
return response.toString();
_157
} catch (IOException e) {
_157
e.printStackTrace();
_157
return null;
_157
}
_157
}
_157
_157
public void joinLeave(View view) {
_157
Button button = findViewById(R.id.btnJoinLeave);
_157
_157
if (isJoined) {
_157
agoraChatClient.logout(true, new CallBack() {
_157
@Override
_157
public void onSuccess() {
_157
showLog("Sign out success!");
_157
runOnUiThread(() -> button.setText("Join"));
_157
isJoined = false;
_157
}
_157
@Override
_157
public void onError(int code, String error) {
_157
showLog(error);
_157
}
_157
});
_157
} else {
_157
agoraChatClient.loginWithAgoraToken(userId, token, new CallBack() {
_157
@Override
_157
public void onSuccess() {
_157
showLog("Signed in");
_157
isJoined = true;
_157
runOnUiThread(() -> button.setText("Leave"));
_157
}
_157
@Override
_157
public void onError(int code, String error) {
_157
if (code == 200) { // Already joined
_157
isJoined = true;
_157
runOnUiThread(() -> button.setText("Leave"));
_157
} else {
_157
showLog(error);
_157
}
_157
}
_157
});
_157
}
_157
}

Chat RESTful API token authentication

To create a new user, use the following curl command:


_7
curl -X POST -H "Authorization: Bearer <YourAgoraAppToken>" -i "https://XXXX/XXXX/XXXX/users" -d '[
_7
{
_7
"username": "user1",
_7
"password": "123",
_7
"nickname": "testuser"
_7
}
_7
]'

The server responds with the user details:


_13
{
_13
"action": "post",
_13
"application": "8be024f0-e978-11e8-b697-5d598d5f8402",
_13
"path": "/users",
_13
"entities": [
_13
{
_13
"uuid": "0ffe2d80-ed76-11e8-8d66-279e3e1c214b",
_13
"username": "user1",
_13
"activated": true,
_13
"nickname": "testuser"
_13
}
_13
]
_13
}

Reference

This section introduces token generator libraries, version requirements, and related documents about tokens.

Token generator libraries

For more examples and source code in other development languages, explore the AgoraDynamicKey open-source repository on GitHub.

Tokens for Agora RTC products

If you use Agora Chat together with the Agora RTC SDK, Agora recommends upgrading to AccessToken 2.

vundefined