> For a complete documentation index, fetch https://docs.voximplant.ai/llms.txt

# Renewable token authorization

Storing and saving passwords inside applications is not safe. For better security, our SDK provides two additional login methods: with [one-time login keys](/platform/sdks/authorization-onetimekey) and with renewable tokens. Keys omit the need to store passwords by using your own backend that will generate a one-time login key each time your application needs to log in to the Voximplant cloud.

Although the keys are very secure, they should be created by your own backend, while the "tokens" can be used entirely on the SDK side with some security and usability trade-offs that are explained in this article.

After a successful login with a username and a password, the **AuthResult** event is fired by an SDK.

The actual way to receive the event depends on the SDK platform. For the Web SDK, you should use the **addEventListener** method with the **VoxImplant.Events.AuthResult** identifier, for Android an object should implement the **VoxImplantCallback** interface with the **onLoginSuccessful** method, and the object should be registered with the **setCallback** method, and so on. Please refer to the target SDK documentation for the details.

The **AuthResult** event comes with the **tokens** object that contains information about the login tokens. The most important field in that object is the **accessToken**, which can be used with a special version of the **login** method in place of a password. The special versions of the **login** method are named according to the target platform style guide. For example, for the Web SDK, it will be the [loginWithToken](https://voximplant.com/docs/references/websdk/voximplant/client#loginwithtoken) method.

Saving the token instead of a password removes a "password disclosure" vulnerability. But if the token itself is stolen it **can** be used to log in. For the additional security, the token lifespan is limited (1 month by default, but can be changed in the future).

The token should be refreshed periodically by an application using the special **refreshToken** token and the corresponding "refresh token" method. The "refresh token" method is also named according to the target platform style guide. For example, for the Web SDK, it will be the [tokenRefresh](https://voximplant.com/docs/references/websdk/voximplant/client#tokenrefresh) method.

The lifespans for both tokens are received alongside the token strings: **accessExpire** specifies the access token lifespan in seconds and **refreshExpire** specifies the refresh token lifespan in seconds.

## Example

The following code illustrates how **loginWithToken** works in the Web SDK. Create an **index.html** file with this code and don't forget to change the value of the HTML inputs. Then serve the file with the local server like [Web Server for Chrome](https://chrome.google.com/webstore/detail/web-server-for-chrome/ofhbbkphhbklhfoeikjpcbhemlocgigb?hl=en) or the [live-server](https://www.npmjs.com/package/live-server) utility.

```html title="HTML"
<!DOCTYPE html>
<html lang="en">

<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <meta http-equiv="X-UA-Compatible" content="ie=edge">
  <script type="text/javascript" src="//cdn.voximplant.com/edge/voximplant.min.js"></script>
  <title>Tokens</title>
</head>

<body>
  <input type="text" placeholder="user name" id="username" value="user1"><br />
  <input type="text" placeholder="application" id="application" value="someapplication"><br />
  <input type="text" placeholder="account" id="account" value="accountname"><br />
  <br />
  <input type="password" placeholder="password" id="password"><br />
  <button onclick="loginButton()">Log in</button>
  <script>
    const vox = VoxImplant.getInstance();
    let token;

    vox.init({
      micRequired: true
    });

    vox.addEventListener(VoxImplant.Events.SDKReady, handleSDKReady);

    function handleSDKReady() {
      vox.connect();
      vox.addEventListener(VoxImplant.Events.ConnectionEstablished, () => {
        if (typeof console != "undefined") console.log("Connected to Voximplant:" + vox.connected());
      });
      vox.addEventListener(VoxImplant.Events.ConnectionFailed, handleConnectionFailed);

      document.querySelector("button").onclick = function loginButton() {

        const username = document.querySelector("#username").value;
        const application = document.querySelector("#application").value;
        const account = document.querySelector("#account").value;
        const password = document.querySelector("#password").value;

        if (localStorage.getItem('token')) {

          vox.addEventListener(VoxImplant.Events.AuthResult, e => {
            console.log(`Login with the token: ${e.result}`);
          });

          vox.loginWithToken(`${username}@${application}.${account}.voximplant.com`, localStorage.getItem('token'));

        } else {

          vox.addEventListener(VoxImplant.Events.AuthResult, e => {
            token = e.tokens.accessToken;
            localStorage.setItem('token', token);
            console.log(`Login with the provided credentials: ${e.result}`);
          });

          vox.login(`${username}@${application}.${account}.voximplant.com`, password);

        }
      }

      function handleConnectionFailed(e) {
        if (typeof console != "undefined") console.log("Connection to VoxImplant failed:" + e.message);
      }
    }
  </script>
</body>

</html>
```

Open the link provided by your local web server in a browser and open the developer console. Then, specify the use password in the empty input, and click **Log in**. This will log your user in (you will see "Login with the provided credentials: true" in the console) and save a generated token to localStorage.

After that, you can refresh the page and click **Log in** without specifying the user password. The Web SDK will use the token from localStorage and log your user in successfully (you will see "Login with the token: true" in the console).