Menu

Expand
Rate this page:

Issuing Sync Tokens

In any Sync application, your work will span two components.

  • An SDK-driven client app (browser, iOS, Android), where users interact with Sync objects.
  • A backend server which vouches for your users' identities by providing Access Tokens.

Since any Twilio SDK-driven app requires an Access Token to run, most will have code like the below to retrieve a token.

function fetchAccessToken(handler) {
  // We use jQuery to make an Ajax request to our server to retrieve our 
  // Access Token
  $.getJSON('/token', function(data) {
      // The data sent back from the server should contain a long string, which
      // is the token you'll need to initialize the SDK. This string is in a format
      // called JWT (JSON Web Token) - more at http://jwt.io
      console.log(data.token);

      // Since the starter app doesn't implement authentication, the server sends
      // back a randomly generated username for the current client, which is how
      // they will be identified while sending messages. If your app has a login
      // system, you should use the e-mail address or username that uniquely identifies
      // a user instead.
      console.log(data.identity);

      handler(data);
  });
}

In this guide, we'll examine how to handle this request on the server and create a valid token for the client.

Minting an Access Token in your Backend

On the server we must decide, based on the token request that was sent to us, who the user is and what they should be allowed to do. To do this you might use your existing login system (using session cookies, an API token, or whatever mechanism you use to secure API requests or pages today). You might not care who a user is at all, and assign them a temporary identity. Who the user is and how you determine that will vary from app to app.

Assuming that the requesting user is authorized, your backend should respond with a signed token. Here's an example of generating those tokens in Node.js.

We recommend following the standard URI specification and avoid the following reserved characters ! * ' ( ) ; : @ & = + $ , / ? % # [ ] for values such as identity and friendly name.

require('dotenv').load();
var http = require('http');
var path = require('path');

var AccessToken = require('twilio').jwt.AccessToken;
var SyncGrant = AccessToken.SyncGrant;
var express = require('express'); 

// Create Express webapp
var app = express();
app.use(express.static(path.join(__dirname, 'public')));

/*
Generate an Access Token for a Sync application user - it generates a random
username for the client requesting a token, and takes a device ID as a query
parameter.
*/
app.get('/token', function(request, response) {

    // 
    // This is the most critical part of your backend code, as you must identify the user and (possibly)
    // challenge them with some authentication scheme. To determine the identity, you might use:
    //    * A session datum consistently identifying one anonymous visitor,
    //    * A session key identifying a logged-in user
    //    * OAuth credentials identifying a logged-in user
    //    * A random username for all comers.
    //
    var identity = authenticatedSenderOf(request);

    // Create a "grant" identifying the Sync service instance for this app.
    var syncGrant = new SyncGrant({
        serviceSid: process.env.TWILIO_SYNC_SERVICE_SID,
    });

    // Create an access token which we will sign and return to the client,
    // containing the grant we just created and specifying his identity.
    var token = new AccessToken(
        process.env.TWILIO_ACCOUNT_SID,
        process.env.TWILIO_API_KEY,
        process.env.TWILIO_API_SECRET
    );
    token.addGrant(syncGrant);
    token.identity = identity;

    // Serialize the token to a JWT string and include it in a JSON response
    response.send({
        identity: identity,
        token: token.toJwt()
    });
});

// Create http server and run it
var server = http.createServer(app);
var port = process.env.PORT || 3000;
server.listen(port, function() {
    console.log('Express server running on *:' + port);
});

Applying the minted token to your SDK

Access Token in hand, we can now initialize the Sync SDK on the client to start doing fun stuff like subscribing to Sync objects. Here's how you would use the token string to initialize the client in JavaScript.

fetchAccessToken(initializeSync);

function initializeSync(tokenResponse) {
  var syncClient = new Twilio.Sync.Client(tokenResponse.token);

  // Use syncClient here
}

After you've initialized the client, you can access all of the SDK's features.

Handling Token Expiry

After supplying the access token to Sync SDK initially, renewing the token prior to its expiry is important for ensuring that your Sync application is a great user experience. For long living applications, you should refresh the token when either tokenAboutToExpire or tokenExpired events occur. Handling just one of them is sufficient. The tokenAboutToExpire trigger takes place three minutes before the JWT access token expiry.

syncClient.on('tokenAboutToExpire', function() {
  // Obtain a JWT access token: https://www.twilio.com/docs/sync/identity-and-access-tokens
  var token = '<your-access-token-here>';
  syncClient.updateToken(token);
}); 
Rate this page:

Need some help?

We all do sometimes; code is hard. Get help now from our support team, or lean on the wisdom of the crowd by visiting Twilio's Stack Overflow Collective or browsing the Twilio tag on Stack Overflow.

Loading Code Sample...
        
        
        

        Thank you for your feedback!

        Please select the reason(s) for your feedback. The additional information you provide helps us improve our documentation:

        Sending your feedback...
        🎉 Thank you for your feedback!
        Something went wrong. Please try again.

        Thanks for your feedback!

        thanks-feedback-gif