diff --git a/shared/video-sdk/authentication-workflow/index.mdx b/shared/video-sdk/authentication-workflow/index.mdx
index f160df441..c706638f2 100644
--- a/shared/video-sdk/authentication-workflow/index.mdx
+++ b/shared/video-sdk/authentication-workflow/index.mdx
@@ -6,7 +6,7 @@ import ProjectImplement from '@docs/shared/video-sdk/authentication-workflow/pro
import ProjectTest from '@docs/shared/video-sdk/authentication-workflow/project-test/index.mdx';
import Reference from '@docs/shared/video-sdk/authentication-workflow/reference/index.mdx';
-Authentication is the process of validating the identity of each user before they access a system. uses digital tokens to authenticate users and their privileges. A token is a string used to verify user privileges when joining a channel. When a user connects to and passes in the token, the server verifies the user's identity and permissions based on the information in the token.
+Authentication is the process of validating the identity of each user before they access a system. uses digital [tokens](./video-calling/reference/glossary?#token) to authenticate users and their privileges. A token is a string used to verify user privileges when joining a [channel](./video-calling/reference/glossary?#channel). When a user connects to and passes in the token, the server verifies the user's identity and permissions based on the information in the token.
## Understand the tech
@@ -37,8 +37,8 @@ Before starting, ensure that you have:
* Implemented the [SDK quickstart](../get-started/get-started-sdk) in your project.
* The following information from [Agora Console](https://console.agora.io/v2):
- * App ID: A unique string generated by Agora that identifies your project.
- * App Certificate: A string generated by Agora Console to enable token authentication. To obtain the App Certificate for your project, enable primary certificate.
+ * [App ID](./video-calling/reference/glossary?#app-id): A unique string generated by Agora that identifies your project.
+ * [App Certificate](./video-calling/reference/glossary?#app-certificate): A string generated by Agora Console to enable token authentication. To obtain the App Certificate for your project, enable primary certificate.
@@ -287,9 +287,10 @@ if __name__ == "__main__":
+Refer to this [quick guide](#manually-deploy-a-token-generator-locally) on how to deploy a token generator locally.
-The code samples presented on this page use an integer user ID to generate a token. To use a string user ID, refer to the [Token Generator code repository](https://github.com/AgoraIO/Tools/tree/master/DynamicKey/AgoraDynamicKey) to view the corresponding code sample in the desired language.
+The code samples presented on this page use an integer [user ID](./video-calling/reference/glossary?#user-iduid) to generate a token. To use a string user ID, refer to the [Token Generator code repository](https://github.com/AgoraIO/Tools/tree/master/DynamicKey/AgoraDynamicKey) to view the corresponding code sample in the desired language.
diff --git a/shared/video-sdk/authentication-workflow/project-implementation/web.mdx b/shared/video-sdk/authentication-workflow/project-implementation/web.mdx
index 6f768bf3b..e8cead8ce 100644
--- a/shared/video-sdk/authentication-workflow/project-implementation/web.mdx
+++ b/shared/video-sdk/authentication-workflow/project-implementation/web.mdx
@@ -3,210 +3,229 @@ import CodeBlock from '@theme/CodeBlock';
### Use a token
-This section shows you how to integrate token authentication in your .
-
-1. Open the [SDK quickstart](../get-started/get-started-sdk) project you created earlier.
-
-1. In `index.html`, include an HTTP client library such as `axios` for sending token requests to the authentication server.
-
- ```html
-
-
- Token demo
-
-
-
- Token demo
-
-
-
-
- ```
-
-1. Add a `fetchToken` method to retrieve a token from your token server to join a channel.
-
- ```js
- // Retrieve a token from your token server
- function fetchToken(uid, channelName, tokenRole) {
-
- return new Promise(function (resolve) {
- axios.post('http:///fetch_rtc_token', {
- uid: uid,
- channelName: channelName,
- role: tokenRole
- }, {
- headers: {
- 'Content-Type': 'application/json; charset=UTF-8'
- }
- })
- .then(function (response) {
- const token = response.data.token;
- resolve(token);
+This section shows you how to integrate [token](./video-calling/reference/glossary?#token) authentication in your .
+
+1. **Open the [SDK quickstart](../get-started/get-started-sdk) project** you created earlier.
+
+1. **Edit index.html**
+ In `index.html`, include an HTTP client library such as `axios` for sending token requests to the authentication server.
+
+ ```html
+
+
+
+
+ Token Demo
+
+
+
+
+
+
+ Token Demo
+
+
+
+ ```
+
+1. **Edit AgoraLogic.js**
+ Add necessary code to `AgoraLogic.js` in order to create fetch token requests to the token generation server.
+
+ 1. **Complete sample code**
+ For a complete implementation of token authentication in `AgoraLogic.js`, refer to the following code:
+
+
+ Sample code for basic authentication
+
+ {`var rtc = {
+ // Set local audio track and video track
+ localAudioTrack: null,
+ localVideoTrack: null,
+ };
+
+ var options = {
+ // Fill in app ID
+ appId: "",
+ // Fill in a channel name
+ channel: "test",
+ // Set the user as host or audience
+ role: "host"
+ };
+
+ // Get a token from your token server
+
+ function fetchToken(uid, channelName, tokenRole) {
+
+ return new Promise(function (resolve) {
+ axios.post('http:///fetch_rtc_token', {
+ uid: uid,
+ channelName: channelName,
+ role: tokenRole
+ }, {
+ headers: {
+ 'Content-Type': 'application/json; charset=UTF-8'
+ }
})
- .catch(function (error) {
- console.log(error);
- });
- })
- }
- ```
-
-1. Use the token to join a channel
-
- ```js
- // Assign the obtained token to the token parameter in the join method
- let token = await fetchToken(uid, options.channel, 1);
- await client.join(options.appId, options.channel, token, uid);
- ```
-
-### Token expiration
-
-After you join a channel using a token, the SDK triggers the `token-privilege-will-expire` callback, 30 seconds before the token is set to expire. Upon receiving this callback, retrieve a fresh token from the server and call the `renewToken` method to pass the newly generated token to the SDK.
-
- ```javascript
- client.on("token-privilege-will-expire", async function () {
- // When you receive the token-privilege-will-expire callback, request a fresh token from the server
- let token = await fetchToken(uid, options.channel, 1);
- // Call renewToken to pass the new token to the SDK
- await client.renewToken(token);
- });
- ```
-
-When the token expires, the SDK triggers the `token-privilege-did-expire` callback. In this case, retrieve a fresh token from the server and call the `join` method to rejoin the channel with the new token:
-
- ```javascript
- // The token expired.
- client.on("token-privilege-did-expire", async function () {
- console.log("Fetching a new token")
- // Request a new token from the server
- let token = await fetchToken(uid, options.channel, 1);
- console.log("Rejoining the channel with new token")
- // Call join to rejoin the channel
- await client.join(options.appId, options.channel, token, uid);
- });
- ```
-
-### Complete sample code
-
-For a complete implementation of token authentication, refer to the following code:
-
-
- Sample code for basic authentication
-
- {`var rtc = {
- // Set local audio track and video track
- localAudioTrack: null,
- localVideoTrack: null,
- };
-
- var options = {
- // Fill in app ID
- appId: "",
- // Fill in a channel name
- channel: "test",
- // Set the user as host or audience
- role: "host"
- };
-
- // Get a token from your token server
-
- function fetchToken(uid, channelName, tokenRole) {
-
- return new Promise(function (resolve) {
- axios.post('http:///fetch_rtc_token', {
- uid: uid,
- channelName: channelName,
- role: tokenRole
- }, {
- headers: {
- 'Content-Type': 'application/json; charset=UTF-8'
- }
+ .then(function (response) {
+ const token = response.data.token;
+ resolve(token);
+ })
+ .catch(function (error) {
+ console.log(error);
+ });
})
- .then(function (response) {
- const token = response.data.token;
- resolve(token);
- })
- .catch(function (error) {
- console.log(error);
+ }
+
+ async function startBasicCall() {
+
+ const client = AgoraRTC.createClient({ mode: "live", codec: "vp8" });
+ client.setClientRole(options.role);
+ const uid = 123456;
+
+ // Assign the obtained token to the token parameter of the join method, and join the channel
+ let token = await fetchToken(uid, options.channel, 1);
+
+ await client.join(options.appId, options.channel, token, uid);
+ rtc.localAudioTrack = await AgoraRTC.createMicrophoneAudioTrack();
+ rtc.localVideoTrack = await AgoraRTC.createCameraVideoTrack();
+ await client.publish([rtc.localAudioTrack, rtc.localVideoTrack]);
+ const localPlayerContainer = document.createElement("div");
+ localPlayerContainer.id = uid;
+ localPlayerContainer.style.width = "640px";
+ localPlayerContainer.style.height = "480px";
+ document.body.append(localPlayerContainer);
+
+ rtc.localVideoTrack.play(localPlayerContainer);
+
+ console.log("publish success!");
+
+ client.on("user-published", async (user, mediaType) => {
+ await client.subscribe(user, mediaType);
+ console.log("subscribe success");
+
+ if (mediaType === "video") {
+ const remoteVideoTrack = user.videoTrack;
+ const remotePlayerContainer = document.createElement("div");
+ remotePlayerContainer.textContent = "Remote user " + user.uid.toString();
+ remotePlayerContainer.style.width = "640px";
+ remotePlayerContainer.style.height = "480px";
+ document.body.append(remotePlayerContainer);
+ remoteVideoTrack.play(remotePlayerContainer);
+
+ }
+
+ if (mediaType === "audio") {
+ const remoteAudioTrack = user.audioTrack;
+ remoteAudioTrack.play();
+ }
+
+ client.on("user-unpublished", user => {
+ const remotePlayerContainer = document.getElementById(user.uid);
+ remotePlayerContainer.remove();
});
- })
- }
-
- async function startBasicCall() {
-
- const client = AgoraRTC.createClient({ mode: "live", codec: "vp8" });
- client.setClientRole(options.role);
- const uid = 123456;
-
- // Assign the obtained token to the token parameter of the join method, and join the channel
- let token = await fetchToken(uid, options.channel, 1);
-
- await client.join(options.appId, options.channel, token, uid);
- rtc.localAudioTrack = await AgoraRTC.createMicrophoneAudioTrack();
- rtc.localVideoTrack = await AgoraRTC.createCameraVideoTrack();
- await client.publish([rtc.localAudioTrack, rtc.localVideoTrack]);
- const localPlayerContainer = document.createElement("div");
- localPlayerContainer.id = uid;
- localPlayerContainer.style.width = "640px";
- localPlayerContainer.style.height = "480px";
- document.body.append(localPlayerContainer);
-
- rtc.localVideoTrack.play(localPlayerContainer);
-
- console.log("publish success!");
-
- client.on("user-published", async (user, mediaType) => {
- await client.subscribe(user, mediaType);
- console.log("subscribe success");
-
- if (mediaType === "video") {
- const remoteVideoTrack = user.videoTrack;
- const remotePlayerContainer = document.createElement("div");
- remotePlayerContainer.textContent = "Remote user " + user.uid.toString();
- remotePlayerContainer.style.width = "640px";
- remotePlayerContainer.style.height = "480px";
- document.body.append(remotePlayerContainer);
- remoteVideoTrack.play(remotePlayerContainer);
-
- }
-
- if (mediaType === "audio") {
- const remoteAudioTrack = user.audioTrack;
- remoteAudioTrack.play();
- }
-
- client.on("user-unpublished", user => {
- const remotePlayerContainer = document.getElementById(user.uid);
- remotePlayerContainer.remove();
+
});
- });
+ // When you receive the token-privilege-will-expire callback, request a new token from the server and call renewToken to pass the new token to the SDK
+ client.on("token-privilege-will-expire", async function () {
+ let token = await fetchToken(uid, options.channel, 1);
+ await client.renewToken(token);
+ });
- // When you receive the token-privilege-will-expire callback, request a new token from the server and call renewToken to pass the new token to the SDK
- client.on("token-privilege-will-expire", async function () {
- let token = await fetchToken(uid, options.channel, 1);
- await client.renewToken(token);
- });
+ // When you receive the token-privilege-did-expire callback, request a new token from the server and call join to rejoin the channel.
+ client.on("token-privilege-did-expire", async function () {
+ console.log("Fetching a new token")
+ let token = await fetchToken(uid, options.channel, 1);
+ console.log("Rejoining the channel with a new token")
+ await client.join(options.appId, options.channel, token, uid);
+ });
- // When you receive the token-privilege-did-expire callback, request a new token from the server and call join to rejoin the channel.
- client.on("token-privilege-did-expire", async function () {
- console.log("Fetching a new token")
+ }
+
+ startBasicCall()`}
+
+
+
+ Replace `` with your [app ID](./video-calling/reference/glossary?#app-id), which must be consistent with the app ID you specified in the server configuration. Update `` with the host URL and port of the local Golang server you have deployed. For example `99.9.9.99:8082`.
+
+ Build and run the project on the local device, the performs the following operations:
+
+ * Obtains a token from your token server.
+ * Joins the [channel](./video-calling/reference/glossary?#channel).
+ * Automatically renews the token when it is about to expire.
+ 1. **Understand the code**
+ 1. **Add a `fetchToken` method** to retrieve a token from your token server to join a channel.
+
+ ```js
+ // Retrieve a token from your token server
+ function fetchToken(uid, channelName, tokenRole) {
+
+ return new Promise(function (resolve) {
+ axios.post('http:///fetch_rtc_token', {
+ uid: uid,
+ channelName: channelName,
+ role: tokenRole
+ }, {
+ headers: {
+ 'Content-Type': 'application/json; charset=UTF-8'
+ }
+ })
+ .then(function (response) {
+ const token = response.data.token;
+ resolve(token);
+ })
+ .catch(function (error) {
+ console.log(error);
+ });
+ })
+ }
+ ```
+
+ 1. **Use the token to join a channel**
+
+ ```js
+ // Assign the obtained token to the token parameter in the join method
let token = await fetchToken(uid, options.channel, 1);
- console.log("Rejoining the channel with a new token")
await client.join(options.appId, options.channel, token, uid);
- });
+ ```
- }
+ 1. **Token expiration**
- startBasicCall()`}
-
-
+ After you join a channel using a token, the SDK triggers the `token-privilege-will-expire` callback, 30 seconds before the token is set to expire. Upon receiving this callback, retrieve a fresh token from the server and call the `renewToken` method to pass the newly generated token to the SDK.
+
+ ```javascript
+ client.on("token-privilege-will-expire", async function () {
+ // When you receive the token-privilege-will-expire callback, request a fresh token from the server
+ let token = await fetchToken(uid, options.channel, 1);
+ // Call renewToken to pass the new token to the SDK
+ await client.renewToken(token);
+ });
+ ```
+
+ When the token expires, the SDK triggers the `token-privilege-did-expire` callback. In this case, retrieve a fresh token from the server and call the `join` method to rejoin the channel with the new token:
+
+ ```javascript
+ // The token expired.
+ client.on("token-privilege-did-expire", async function () {
+ console.log("Fetching a new token")
+ // Request a new token from the server
+ let token = await fetchToken(uid, options.channel, 1);
+ console.log("Rejoining the channel with new token")
+ // Call join to rejoin the channel
+ await client.join(options.appId, options.channel, token, uid);
+ });
+ ```
- Replace `` with your app ID, which must be consistent with the app ID you specified in the server configuration. Update `` with the host URL and port of the local Golang server you have deployed. For example `99.9.9.99:8082`.
-Build and run the project on the local device, the performs the following operations:
-* Obtains a token from your token server.
-* Joins the channel.
-* Automatically renews the token when it is about to expire.
\ No newline at end of file