Your First Socialtables App

Introduction

This tutorial covers the necessary steps to build a basic Express app which interacts with the Socialtables API on behalf of your users. We'll cover the following topics:

  • registering your app with Socialtables
  • user authentication
  • getting information about a user

If you're not familiar with Express, you may also want to read the Express docs. You can find a completed example project implementing this tutorial's instructions, as well as some examples of interactions with user data, on Github.

Registering Your App With Socialtables

In order to interact with Socialtables, your app needs an OAuth client ID and secret. To obtain these credentials, you'll want to create an app through our developer portal.

Once you have created an app, you should see an OAuth client ID and secret on its detail page. Write that down.

User Authentication

When a user authenticates through Socialtables, an app receives an OAuth bearer token which is used to make API calls on their behalf. This section focuses on the necessary steps to obtain a bearer token through an authorization code grant.

Setting Up Your Routes

To complete an authorization code handshake, you'll need to create a mechanism to direct the user to Socialtables' auth page, add a handler for the ensuing redirect, and finally implement an API call to exchange the authorization code for a bearer token.

Let's start with initiating the handshake. We'll create a route which will direct the user to https://auth.socialtables.com/oauth/authorize.

/**
 * Route which initiates an OAuth authorization_code grant handshake with Socialtables
 */
app.get("/oauth/login-with-socialtables", function(req, res) {

    var oauthAuthorizeURL = "https://auth.socialtables.com/oauth/authorize" +
        "?client_id=" + encodeURIComponent( YOUR_CLIENT_ID ) +
        "&redirect_uri=" + encodeURIComponent( YOUR_REDIRECT_ENDPOINT_URL ) +
        "&grant_type=authorization_code" +
        "&response_type=code";

    res.redirect(oauthAuthorizeURL);
});

Here's an explanation of the query parameters in this redirect:

  • client_id: (required) the OAuth client ID for your app
  • redirect_uri: (required) the URI to which Socialtables will redirect the user after authorization occurs
  • grant_type: (required) the type of OAuth grant in use - should always be "authorization_code"
  • response_type: (required) the type of response your app is expecting - should always be "code"

Next, we'll create a handler for the user to return to after authentication.

var request = require("request-promise");

/**
 * Handles authorization code redirect from social tables
 */
app.get("/oauth/redirect", function(req, res) {

    // if the response indicated rejection, report the issue to the user
    if (req.query.error || !req.query.code) {
        res.render("error", {
            error: req.query.error_description || "authorization failed"
        });
    }
    // if we have an authorization_code, request an access_token from the API
    else {
        var authorization_code = req.query.code;
        request({
            method: "POST",
            uri: "https://api.socialtables.com/oauth/token",
            form: {
                code: authorization_code,
                client_id: YOUR_CLIENT_ID,
                client_secret: YOUR_CLIENT_SECRET,
                grant_type: "authorization_code",
                response_type: "token"
            },
            resolveWithFullResponse: true,
            json: true
        })
        .then(function(tokenResp) {

            // if we got a token back, add it to the active session
            // and redirect to the root url; the user is now authenticated
            if (tokenResp.statusCode === 200) {
                if (tokenResp.body) {
                    req.session.oauth_access_token = tokenResp.body.access_token;
                    return res.redirect("/");
                }
            }
            return res.render("error", { error: "failed to get an access token" });
        })
        .catch(function(err) {
            res.render("error", { error: "failed to get an access token" });
        });
    }
});

Note the use of a local session and error handling.

Configuring Your App

In addition to setting up the routes within our project, we'll need to tell Socialtables what URL we will be redirecting users to in advance to keep malicious third-parties from having user credentials sent to them. To do this, navigate to your app's edit page and add your redirect URL.

Getting Information About a User

So you've got an OAuth token, but what can you do with it? Well, for starters, you can use it to get basic information about itself through the /oauth/token GET endpoint, and then used the retrieved user ID to get information about your user using the /users/{userID} GET endpoint. Here's an example of how you can do this in middleware:

// apply middleware to set the current user based on their OAuth bearer token
app.use(function(req, res, next) {

    req.user = null;

    // if the session contains a token, look it up
    if (req.session.oauth_access_token) {

        var authHeaders = {
            Authorization: `Bearer ${req.session.oauth_access_token}`
        };

        // make a request for user details corresponding to the token
        request({
            method: "GET",
            headers: authHeaders,
            uri: "https://api.socialtables.com/4.0/oauth/token",
            json: true
        })
        .then(function(tokenDetails) {

            // look up the user object based on the ID we recieved
            var userID = tokenDetails.id;
            req.userID = tokenDetails.v4_id;
            req.legacyUserID = tokenDetails.legacy_id;
            return request({
                method: "GET",
                headers: authHeaders,
                uri: `https://api.socialtables.com/4.0/users/${userID}`,
                json: true
            });
        })
        .then(function(userDetails) {

            // apply the user object to the request
            req.user = userDetails;
            next();
        })
        .catch(function(err) {
            console.error("Error getting user details", err);
            next();
        });
    }
    // no token, no problem
    else {
        next();
    }
});

Because Socialtables uses a split ID system between the V3 and V4 APIs, we add both to the request before using the V4 ID to retrieve user information.

Completed Example

You can find a completed example project implementing this tutorial's instructions, as well as some examples of interactions with user data, on Github.

results matching ""

    No results matching ""