# Secure authentication with tokens (/en/realtime-media/rtm/build/connect-and-authenticate/authentication-workflow/react-native)

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

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 [#understand-the-tech-5]

    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**

    ![token authentication flow](https://assets-docs.agora.io/images/signaling/authentication-workflow.svg)

    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](../../manage-agora-account#get-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 [#prerequisites-5]

    Ensure that you have:

    * Integrated the Signaling SDK in your project, and implemented the framework functionality from the [SDK quickstart](/en/realtime-media/rtm/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 [#implement-basic-authentication-5]

    In the [SDK quickstart](/en/realtime-media/rtm/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 [#token-generation-code-5]

    Agora provides an open source token generator code repository on [GitHub](https://github.com/AgoraIO/Tools/tree/master/DynamicKey/AgoraDynamicKey). 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](https://github.com/AgoraIO/Tools/blob/master/DynamicKey/AgoraDynamicKey/go/src/rtmtokenbuilder2/rtmtokenbuilder.go)            | [sample.go](https://github.com/AgoraIO/Tools/blob/master/DynamicKey/AgoraDynamicKey/go/sample/rtmtokenbuilder2/sample.go)                                             |
    | PHP      | [buildToken](https://github.com/AgoraIO/Tools/blob/master/DynamicKey/AgoraDynamicKey/php/src/RtmTokenBuilder2.php)                          | [RtmTokenBuilder2Sample.php](https://github.com/AgoraIO/Tools/blob/master/DynamicKey/AgoraDynamicKey/php/sample/RtmTokenBuilder2Sample.php)                           |
    | Python 2 | [buildToken](https://github.com/AgoraIO/Tools/blob/master/DynamicKey/AgoraDynamicKey/python/src/RtmTokenBuilder2.py)                        | [RtmTokenBuilder2Sample.py](https://github.com/AgoraIO/Tools/blob/master/DynamicKey/AgoraDynamicKey/python/sample/RtmTokenBuilder2Sample.py)                          |
    | Python 3 | [buildToken](https://github.com/AgoraIO/Tools/blob/master/DynamicKey/AgoraDynamicKey/python3/src/RtmTokenBuilder2.py)                       | [RtmTokenBuilder2Sample.py](https://github.com/AgoraIO/Tools/blob/master/DynamicKey/AgoraDynamicKey/python3/sample/RtmTokenBuilder2Sample.py)                         |
    | C++      | [buildToken](https://github.com/AgoraIO/Tools/blob/master/DynamicKey/AgoraDynamicKey/cpp/src/RtmTokenBuilder2.h)                            | [RtmTokenBuilder2Sample.cpp](https://github.com/AgoraIO/Tools/blob/master/DynamicKey/AgoraDynamicKey/cpp/sample/RtmTokenBuilder2Sample.cpp)                           |
    | Java     | [buildToken](https://github.com/AgoraIO/Tools/blob/master/DynamicKey/AgoraDynamicKey/java/src/main/java/io/agora/rtm/RtmTokenBuilder2.java) | [RtmTokenBuilder2Sample.java](https://github.com/AgoraIO/Tools/blob/master/DynamicKey/AgoraDynamicKey/java/src/main/java/io/agora/sample/RtmTokenBuilder2Sample.java) |

    ### Generate a token [#generate-a-token-5]

    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](https://github.com/AgoraIO/Tools/tree/master/DynamicKey/AgoraDynamicKey) repository. To generate an RTC token refer to [Secure authentication with tokens](/en/realtime-media/video/build/authenticate-users/deploy-token-server).

    Before proceeding, make sure that you have:

    * [Installed Go](https://golang.org/) 1.14 or above
    * If you are using a Go version lower than 1.16, set the `GO111MODULE` environment variable to `on`.

    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.

    ```go
    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](#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:

    ```bash
    go mod init sampleServer
    ```

    **Install dependencies**

    To install the dependencies, run the following command:

    ```bash
    go get
    ```

    **Start the server**

    To start the server, execute:

    ```bash
    go run server.go
    ```

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

      <CalloutDescription>
        This sample server is for development purposes only. It should not be used in a production environment.
      </CalloutDescription>
    </CalloutContainer>

    ## Reference [#reference-5]

    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 [#buildtoken-api-reference-5]

    This section explains the API parameters and descriptions for generating `AccessToken2` using Golang as an example:

    ```go
    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.                                                                                                               |

    
  
      
  
      
  
      
  
