Using Webtask.io for Secure API Tokens

July 19, 2015 // Tagged in: javascript, authentication

Single Page Applications are awesome. One downside is that static SPAs often have to authenticate with some service or API in order to coordinate some communication, access some data, or connect to other users, and that connection has an inherent security risk:

How do you connect to a secure service from an insecure (client side) source?

There are a multitude of ways to do this, but they usually involve setting up your own server to handle authentication or OAuth to the external service. Here's one way that I recently worked out.

My Goal

  1. Connect a javascript application to Respoke
  2. ... without creating my own server component
  3. ... safely and securely

The Respoke docs have a pretty clearcut way of authenticating - just require their respoke-admin module in your node server, call authenticate with your AppId and AppSecret, and get back a token, then pass that token to your client to start making API calls to Respoke.

Uh oh! Those steps assume I've got a server! What if I want to eliminate that part entirely? Here steps in webtask, an ephemeral, almost-entirely-stateless proxy-esque server for executing code on a server - but not your server. There's nothing to host, it's not constantly running, and you don't have to deploy anything. All you do is create an account, give it some code, get a secure token, and let your clients make requests to that code. Ok, so that was a lot. Let's take a step back:

  1. Create a webtask account at webtask.io

  2. Install their cli tools with npm install -g wt-cli, then follow instructions to authenticate

  1. Create your webtask with wt create task-code.js --secret my_app_secret=mysecretvalue my_app_id=myappid

Complete Working Example

So what does the code in my-task.js actually look like? For my respoke app, it's this basic code, taken almost verbatim from their API documentation example:

There's one tiny complication to this - you can't require npm modules with webtask, so any modules that your code requires (mine requires respoke-admin) have to be included in your task's javascript file directly. This might take some work if you have nested dependencies, but what I did was start in-lining all required modules until it ran successfully, then minified the result. (If you know if a tool that does this, please let me know.)

So my end result is that I have a file called respoke-auth.js:

And I can create my task with

wt create respoke-auth.js --secret my_respoke_app=[redacted] my_respoke_secret=[redacted]

And I get the url: https://webtask.it.auth0.com/api/run/wt-xander_dumaine-gmail_com-0/respoke-auth that can be used in an unauthenticated, client-side context to get a secure auth token to my Respoke account. This example uses this whole flow to make a client connection to Respoke:

Caching and Updating

One downside to the way I created my webtask above is that in order to update my task code, I'd have to re-create my task entirely. This isn't ideal, so instead of passing the code file itself, I can host my code file, and provide the task a url, and it will fetch the code from the URL, each time it's executed.

wt create http://example.com/my-task.js --secret .... This way, you can just update my-task.js as necessary and not affect the webtask.

Bonus

Want a neat way to host that task file with virtually no work at all? Use surge.sh

  1. npm install -g surge
  2. surge

Surge will deploy your static files to their domain (or your own!) and host it for free, with basically no setup. You can do this with github pages, but it takes more setup and configuration.