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-case | Token type | Information required to generate | Maximum validity |
---|---|---|---|
RESTful API calls | Token with app privileges |
| 24 hours |
SDK API calls | Token with user privileges |
| 24 hours |
Prerequisites
In order to follow this procedure, you must have the following:
- A valid Agora account.
- An Agora project with the App Certificate and Agora Chat enabled.
- App ID, OrgName, and AppName of your Agora project. See Enable and Configure Agora Chat Service.
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
This section guides you through setting up a token server. Choose your preferred language and follow the step-by-step procedure.
This sample server code provided in this guide is for demonstration purposes only. Do not use it directly in a production environment.
- Golang
- Node.JS
- Python
- Java
- C++
-
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 -
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
-
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) } }
-
Run the server
In
server.go
, update the values forAppIDd
andAppCertificate
. Use the following command to run the server:go run server.go
The server will start on
http://localhost:8080
. -
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}'
-
-
Create and initialize a Node.js project
Open your terminal and execute the following commands:
mkdir chat-token-server
cd chat-token-server
npm init -y -
Install the required dependencies
The token server code leverages the
ChatTokenBuilder
utility to generate tokens.npm install agora-token
npm install express -
Add the logic to set up a token server
Create a file
index.js
and add the following code:const { ChatTokenBuilder } = require("agora-token");const express = require("express");const app = express();const PORT = process.env.PORT || 8080;// App credentialsconst appId = "YOUR_APP_ID";const appCertificate = "YOUR_APP_CERTIFICATE";// Route to generate a user tokenapp.get("/api/token/generateUserToken", (req, res) => { const account = req.query.account; const expireTimeInSeconds = parseInt(req.query.expireTimeInSeconds) || 3600; if (!account) { return res.status(400).json({ error: "Account parameter is required" }); } try { const token = ChatTokenBuilder.buildAppToken(appId, appCertificate, account, expireTimeInSeconds); res.json({ status: "success", token }); } catch (error) { res.status(500).json({ error: error.message }); }});// Route to generate an app tokenapp.get("/api/token/generateAppToken", (req, res) => { const expireTimeInSeconds = parseInt(req.query.expireTimeInSeconds) || 3600; try { const token = ChatTokenBuilder.buildAppToken(appId, appCertificate, expireTimeInSeconds); res.json({ status: "success", token }); } catch (error) { res.status(500).json({ error: error.message }); }});app.listen(PORT, () => { console.log(`Server running on port ${PORT}`);});
-
Run the server
In
index.js
, update the values forappId
andappCertificate
. Use the following command to run the server:node index.js
-
Test the server
Use the following
curl
requests to test your server:-
Generate a user token
curl "http://localhost:8080/api/token/generateUserToken?account=user123&expireTimeInSeconds=3600"
-
Generate an app token
curl "http://localhost:8080/api/token/generateAppToken?expireTimeInSeconds=3600"
-
-
Create and initialize a Python project
mkdir agora-token-server
cd agora-token-server
python -m venv venv -
Activate the virtual environment
-
Linux/macOS
source venv/bin/activate
-
Windows
venv\Scripts\activate
-
-
Add the dependencies
-
Add the Agora Tools dependency
This implementation uses code from the
AgoraIO/Tools
repository to generate tokens with app and user privileges. Copy thesrc
folder from the repository to theagora-token-server
directory. -
Install Flask and save the dependencies
pip install flask
pip freeze > requirements.txt
-
-
Add the logic to set up a token server
Create a file
app.py
and add the following code:from flask import Flask, request, jsonifyfrom src.ChatTokenBuilder2 import ChatTokenBuilderimport osapp = Flask(__name__)# App credentialsAPP_ID = "YOUR_APP_ID"APP_CERTIFICATE = "YOUR_APP_CERTIFICATE"@app.route("/api/token/generateUserToken", methods=["GET"])def generate_user_token(): """Generates a user token for the Agora service.""" user_id = request.args.get("account") expire = int(request.args.get("expireTimeInSeconds", 3600)) if not APP_ID or not APP_CERTIFICATE: return jsonify({"error": "APP_ID or APP_CERTIFICATE is not set"}), 400 if not user_id: return jsonify({"error": "Missing 'account' parameter"}), 400 token = ChatTokenBuilder.build_user_token(APP_ID, APP_CERTIFICATE, user_id, expire) return jsonify({"token": token})@app.route("/api/token/generateAppToken", methods=["GET"])def generate_app_token(): """Generates an app token for the Agora service.""" expire = int(request.args.get("expireTimeInSeconds", 3600)) if not APP_ID or not APP_CERTIFICATE: return jsonify({"error": "APP_ID or APP_CERTIFICATE is not set"}), 400 token = ChatTokenBuilder.build_app_token(APP_ID, APP_CERTIFICATE, expire) return jsonify({"token": token})if __name__ == "__main__": app.run(host="0.0.0.0", port=3001)
Your folder structure should look like this:
agora-token-server/ ├── src/ # Folder from the AgoraIO/Tools GitHub repository ├── app.py # Main script ├── venv/ # Virtual environment (auto-created) ├── requirements.txt # Dependencies file
-
Run the server
In
app.py
, replaceYOUR_APP_ID
andYOUR_APP_CERTIFICATE
with your Agora credentials. Use the following command to run the server:python app.py
The terminal displays a development URL, such as:
http://127.0.0.1:3001
. Use this URL to access the endpoints. -
Test the server
Use the following curl requests to test your server:
-
Generate a user token
curl "http://localhost:3001/api/token/generateUserToken?account=123456789&expireTimeInSeconds=3600"
-
Generate a app token
curl "http://localhost:3001/api/token/generateAppToken?expireTimeInSeconds=3600"
-
-
Create a Maven project
- In IntelliJ, create a new Maven project.
- Name the project, choose a save location, and click Finish.
-
Add dependencies
To configure your project dependencies, complete the following steps:
-
Open the
<Project name>/pom.xml
file. -
Replace the
<properties>
section with the following:<properties> <maven.compiler.source>11</maven.compiler.source> <maven.compiler.target>11</maven.compiler.target> <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> <spring-boot.version>2.4.3</spring-boot.version></properties><packaging>jar</packaging><dependencyManagement> <dependencies> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-dependencies</artifactId> <version>${spring-boot.version}</version> <type>pom</type> <scope>import</scope> </dependency> </dependencies></dependencyManagement><dependencies> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-configuration-processor</artifactId> </dependency> <dependency> <groupId>commons-codec</groupId> <artifactId>commons-codec</artifactId> <version>1.14</version> </dependency> <dependency> <groupId>com.google.guava</groupId> <artifactId>guava</artifactId> <version>30.0-jre</version> </dependency> <dependency> <groupId>io.agora</groupId> <artifactId>authentication</artifactId> <version>2.0.0</version> </dependency></dependencies><build> <plugins> <plugin> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-maven-plugin</artifactId> <version>2.4.1</version> <executions> <execution> <goals> <goal>repackage</goal> </goals> </execution> </executions> </plugin> </plugins></build>
-
-
Set up application properties
-
Create an
application.properties
file in<Project name>/src/main/resources
. -
Add the following properties to store your app credentials.
app.id=YOUR_APP_ID
app.certificate=YOUR_APP_CERTIFICATE
infoFor app key and RESTful API domain information, refer to Get Agora Chat Project Information.
-
-
Download and configure required packages
To set up your project, follow these steps:
-
Download packages
-
Move packages into your project
- Navigate to your project directory.
- Move the downloaded
media
andchat
packages into the following directory:
<Project name>/src/main/java
.
-
Verify the packages
- Open the project in IntelliJ IDEA.
- Confirm that the
media
andchat
packages are visible under the<Project name>/src/main/java
directory.
-
Rename the packages
Rename the packages for proper name-spacing:
- Change
media
toio.agora.media
. - Change
chat
toio.agora.chat
.
- Change
-
-
Expose an endpoint for token generation
Follow these steps to set up a token generation endpoint:
-
Replace the existing
Main.java
file in theorg.example
package with the following code:package org.example;import org.springframework.boot.SpringApplication;import org.springframework.boot.autoconfigure.SpringBootApplication;@SpringBootApplication(scanBasePackages = "org.example.controller")public class Main { public static void main(String[] args) { // Start the Spring Boot application SpringApplication.run(Main.class, args); System.out.println("Token generation service is running on http://localhost:8080/token/generate"); }}
-
Inside the
org.example
package, create a new package namedcontroller
. -
Add the
TokenController
class:-
Inside the
controller
package, create a new class namedTokenController
. -
Add the following code to the
TokenController
class:package org.example.controller;import io.agora.chat.ChatTokenBuilder2;import org.springframework.beans.factory.annotation.Value;import org.springframework.web.bind.annotation.*;@RestController@RequestMapping("/token")public class TokenController { private final ChatTokenBuilder2 tokenBuilder; // Inject values from application.properties or environment variables @Value("${app.id}") private String appId; @Value("${app.certificate}") private String appCertificate; public TokenController() { this.tokenBuilder = new ChatTokenBuilder2(); } @PostMapping("/generate") public String generateToken( @RequestParam String userId, @RequestParam int expireSeconds, @RequestParam(required = false, defaultValue = "user") String tokenType) { if (tokenType.equalsIgnoreCase("app")) { return tokenBuilder.buildAppToken(appId, appCertificate, expireSeconds); } else if (tokenType.equalsIgnoreCase("user")) { return tokenBuilder.buildUserToken(appId, appCertificate, userId, expireSeconds); } else { throw new IllegalArgumentException("Invalid tokenType. Must be 'user' or 'app'."); } }}
The code uses the ChatTokenBuilder2 library to generate tokens with app and user privileges.
-
-
-
Test the server
-
Click Run to start the server. The server starts on
http://localhost:8080/token/generate
: -
Use the following
curl
requests to test your server:-
User token:
curl -X POST http://localhost:8080/token/generate \
-H "Content-Type: application/x-www-form-urlencoded" \
-d "userId=testUser" \
-d "expireSeconds=3600" \
-d "tokenType=user"
-
App token:
curl -X POST http://localhost:8080/token/generate \
-H "Content-Type: application/x-www-form-urlencoded" \
-d "userId=testUser" \
-d "expireSeconds=3600" \
-d "tokenType=app"
-
-
-
Install OpenSSL.
-
Clone the Agora Tools repository.
git clone https://github.com/AgoraIO/Tools
-
Open the file
DynamicKey/AgoraDynamicKey/cpp/sample/ChatTokenBuilder2Sample.cpp
in your IDE.ChatTokenBuilder2Sample.cpp
#include <cstdlib>
#include <iostream>
#include "../src/ChatTokenBuilder2.h"
using namespace agora::tools;
int main(int argc, char const *argv[]) {
(void)argc;
(void)argv;
// Need to set environment variable AGORA_APP_ID
const char *env_app_id = getenv("AGORA_APP_ID");
std::string app_id = env_app_id ? env_app_id : "";
// Need to set environment variable AGORA_APP_CERTIFICATE
const char *env_app_certificate = getenv("AGORA_APP_CERTIFICATE");
std::string app_certificate = env_app_certificate ? env_app_certificate : "";
std::string channel_name = "7d72365eb983485397e3e3f9d460bdda";
std::string user_id = "test_user_id";
uint32_t expiration_in_seconds = 600;
std::cout << "App Id:" << app_id << std::endl;
std::cout << "App Certificate:" << app_certificate << std::endl;
if (app_id == "" || app_certificate == "") {
std::cout << "Need to set environment variable AGORA_APP_ID and "
"AGORA_APP_CERTIFICATE"
<< std::endl;
return -1;
}
auto user_token = ChatTokenBuilder2::BuildUserToken(
app_id, app_certificate, user_id, expiration_in_seconds);
std::cout << "Chat User Token:" << user_token << std::endl;
auto app_token = ChatTokenBuilder2::BuildAppToken(app_id, app_certificate,
expiration_in_seconds);
std::cout << "Chat App Token:" << app_token << std::endl;
return 0;
} -
Set the required environment variables.
-
Linux/macOS:
export AGORA_APP_ID="your_app_id"
export AGORA_APP_CERTIFICATE="your_app_certificate" -
Windows:
set AGORA_APP_ID=your_app_id
set AGORA_APP_CERTIFICATE=your_app_certificate
-
-
Open a Terminal, navigate to the directory containing
ChatTokenBuilder2Sample.cpp
, and run the following command:g++ -std=c++0x -O0 -I../../ -L. ChatTokenBuilder2Sample.cpp -lz -lcrypto -o ChatTokenBuilder2Sample
This generates an executable named
ChatTokenBuilder2Sample
in the folder -
Run the following command to generate and print your token:
./ChatTokenBuilder2Sample
Chat SDK token authentication
The following code fetches and replaces an expired token for the Agora Chat SDK. It performs the following tasks:
- 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.
- 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.
Chat RESTful API token authentication
To create a new user, use the following curl
command:
The server responds with the user details:
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.