# Use tokens (/en/realtime-media/video/build/authenticate-users/authentication-workflow/blueprint)

> For AI agents: see the complete documentation index at [llms.txt](/llms.txt).

To protect your business, it is best practice to authenticate every client that joins a channel. This guide explains how to fetch an authentication token from your token server, use it to join a channel, and renew the token when it expires.

## Understand the tech [#understand-the-tech]

When a user attempts to connect to an Agora channel, your app retrieves a token from the token server in your security infrastructure. Your app then sends this token to Agora SDRTN® for authentication. Agora SDRTN® reads the information stored in the token to validate the request.

The following figure shows the call flow you implement to create step-up-authentication with Agora Video Calling:

<Accordions>
  <Accordion title="Token authentication flow">
    ![token authentication flow](https://assets-docs.agora.io/images/video-sdk/token-authentication.svg)
  </Accordion>
</Accordions>

## Prerequisites [#prerequisites]

Before starting, ensure that you have:

* Implemented the [Quickstart](/en/realtime-media/video/get-started-sdk) in your project.

* Deployed a token server using either of the following guides:

  * [Deploy a token server](/en/realtime-media/video/build/authenticate-users/deploy-token-server)
  * [Deploy a middleware server](/en/realtime-media/video/build/authenticate-users/middleware-token-server)

## Implement basic authentication [#implement-basic-authentication]

This section shows you how to implement basic authentication by acquiring a token and using it to join a channel.

      
  
      
  
      
  
      
  
      
  
      
  
      
  
      
  
      
  
      
    ### Use a token to join a channel [#use-a-token-to-join-a-channel-8]

    The client requests a token from your authentication server corresponding to the user ID and the channel name. You use the received token to join a channel.

    ```cpp
    // Channel name
    const char* channelId;
    // User ID
    int uid = 0
    // Request a token from the server corresponding to channelId and uid
    const char* token = getToken();
    // Set channel media options
    ChannelMediaOptions options;
    // Set the user role as host
    options.clientRoleType = CLIENT_ROLE_TYPE::CLIENT_ROLE_BROADCASTER;
    // Join the channel
    m_rtcEngine->joinChannel(token, channelId, uid, options);
    ```

    ### Token expiration [#token-expiration-4]

    After you join a channel using a token, the SDK triggers an `onTokenPrivilegeWillExpire` callback, 30 seconds before the token is set to expire.

    When the token expires, the SDK triggers an `onRequestToken` callback. After receiving the callback, you regenerate a new token on the server side, and then update the token in one of the following ways:

    #### Single channel use-case [#single-channel-use-case-4]

    * Call `renewToken` to pass in the newly generated Token (Recommended).

    * Call `updateChannelMediaOptions` to update the token.

    * Call `leaveChannel` \[2/2] to leave the current channel, and then pass in a new token when calling `joinChannel` \[2/2] to rejoin the channel.

    #### Multi-channel use-case [#multi-channel-use-case-4]

    If you call `joinChannelEx` to join multiple channels, call the `updateChannelMediaOptionsEx` method to update the token.

    The following sample code demonstrates how to call `renewToken` to update the token upon receiving an `onTokenPrivilegeWillExpire` callback notification.

    ```cpp
    class CJoinChannelVideoByTokenRtcEngineEventHandler
        : public IRtcEngineEventHandler
    {
    public:
        // Triggered when a token is about to expire
        virtual void onTokenPrivilegeWillExpire(const char* token) {
        // Request to generate a fresh token
        const char* token = getToken();
        // Renew token
        m_rtcEngine->renewToken(token);
        }
    }
    ```

    
  
      
  
      
  
<CalloutContainer type="warning">
  <CalloutTitle>
    Note
  </CalloutTitle>

  <CalloutDescription>
    The user ID and channel name used to join a channel must be consistent with the values used to generate the token.
  </CalloutDescription>
</CalloutContainer>

## Reference [#reference]

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

      
  
      
  
      
  
      
  
      
  
      
  
      
  
      
  
      
  
      
  
      
  
