One of the questions I had in my last post was about how to manage sessions and login to a Rails app from a WebExtensions client. For example, let’s say your Rails app provides a Profiles resource that you handle in Rails with a route GET /profiles/:id. Let’s say you provide an API endpoint as well, at GET /api/v1/profiles/:id. From your WebExtensions script, you would issue the XHR like so:

var url = "http://localhost:4000/api/v1/profiles/2";
var req = new XMLHttpRequest();
req.open('GET', url, false);
req.send(null);
console.log(req.responseText);

Most likely, the endpoint will be protected by some sort of authentication check. The nifty thing is if you happen to have cookies from, say, having logged in through the web interface of the app, those are automatically sent when you send the XHR, and you can potentially be authenticated that way. But more typically for an API, you might be using Rails token authentication. Rails provides authenticate_or_request_with_http_token, which will look at the Authorization request header for a token that will be used instead of cookies. So you’ll need to do two things:

  1. get the token, and
  2. set it in the request header.

Conventionally, you might see the token made available by the app through some sort of user settings page where the user can copy and paste it into the extension to use for authorization. There might be a more automated way to do this, though.

The second part can be achieved by adding the following to the above snippet:

  var url = "http://localhost:4000/api/v1/profiles/2";
  var req = new XMLHttpRequest();
  req.open('GET', url, false);
+ req.setRequestHeader('AUTHORIZATION', 'Token token=your_token_here');
  req.send(null);
  console.log(req.responseText);

With this, Rails should be able to pick out the token from the request header and use that to authenticate the request and get your JSON response.

What’s next?

So while you now theoretically have full access to the API, there’s another thing to consider called Cross Origin Resource Sharing (CORS). Basically, it’s a way for a server to specify access control to resources from cross-site scripts, which is what our browser extension is. For example, we don’t want a malicious script to be able to send DELETE requests or otherwise mess with your data. CORS is a way to permit or deny requests, based on where the originating script is coming from.

This may not be an issue because a malicious script would somehow have to get access to the authentication token. But this may mean extra server-side setup depending on how this protocol is enforced across browsers. I’ll investigate the details in the next few days.