Thursday, January 19, 2012

jsOAuth in the browser, my response to OAuth in web browsers

  • Developer:
  • We are on a look out for a Javascript OAuth library that works in browsers.
  • Rob Griffiths:
  • There are some things you need to consider when trying to get OAuth working in the browser using Javascript.
  • Firstly, Javascript source is viewable by anyone with the inclination to do so, this means that your OAuth Key and Secret are publicly accessible, meaning that an attacker could use your credentials to sign requests and gain access tokens, in theory at least. In my opinion the attacker would have to fool a user into thinking they were your site, which isn't too hard but users are stupid and can be fooled easily.
  • Secondly, if your site contacts a third party webservice, you'll be bound by in build browser security as you are making a cross domain request. The security disables any XHR from talking to a domain other than the one it was created on.
  • Unless you use CORS (cross origin resource sharing), however most web services dont support this, which is a shame as this would make the web a better place allowing sites to interact at the client level creating interesting application mashups.
  • So I'd ask this;
  • - Does the webservice you're planning to use support CORS?
  • - Do you have a plan to hide your secret in plain sight?
  • Most people solve these issue by building a server-side script to proxy their XHR.
Thursday, October 27, 2011

Why make Promises

Whatever you may call them, Promises, Futures or even Deferred the concept is the same. You ask an asynchronous task to do something, and it gives you a promised result back instantly which you can then act upon.

Take this trivial example in javascript:

var results = searchTwitter("Starwars");
filterByAuthor("@darthvader1977", results);
displayTweets(results);

Now wouldn’t that be great? Looks synchronous but behaves asynchronously? Sadly, I believe that this would require a language construct not native to most programming languages.

There are a few promise libraries written in Javascript that provide an API we can utilise on our previous example.

searchTwitter("Starwars").
    then(filterBydarthvader1977).
    then(displayTweets);

An heres where I’m confused. Why is this better then doing:

searchTwitter("Starwars", function (results) {
    displayTweets(filterByAuthor("@darthvader1977", results));
});

Yes I guess, yes it does look prettier and more concise, and the API is explicit in its intent, but is that enough? This covers the Promises/A proposal as detailed on the CommonJS wiki. In my opinion pretty useless, at least in Javascript. From what I can tell, all of the proposals seem require the supply of a callback of some sort. This to me is interesting as I thought the whole idea behond promises was to get rid of the layers of nested callback, not just to reduce them.

So this leads me to an idea, which after a conversation with a collegue seems to make sense. So lets start with an example.

var tweets = searchTwitter("Startwars");
tweets.filterByAuthor("@darthvader1977");
tweets.display();

As you can see, we call method on the tweets variable. I’m assuming that the searchTwitter method instantly returns a tweets object, with each method queuing the call until the asynchronous call to searchTwitter completes, which then calls each method in turn in the order it was invoked.

Now I’m certain this isn’t a new idea, and there must be a library out there or a specification, can someone tell me where?

Friday, April 15, 2011

Using OpenStreetMap.org with the Google map API

Using a custom map type, its really simple to use the Google map API with tiles from open street map.

function OSMMapType() {}
OSMMapType.prototype = {
	tileSize: new google.maps.Size(256,256),
	maxZoom: 18,
	getTile: function(coord, zoom, ownerDocument) {
		var tileUrl = 'http://tile.openstreetmap.org/' + zoom + '/' + coord.x + '/' + coord.y + '.png';

		var tile = ownerDocument.createElement('img');
		tile.width = this.tileSize.width;
		tile.height = this.tileSize.height;
		tile.src = tileUrl;

		return tile;
	}
};

With this map type we instantiate a google map, and tell it to use our custom type

var latLng = new google.maps.LatLng(54.572061655658494, -3.7408447265625);
var map = new google.maps.Map(document.getElementById("map"), {
	zoom: 5,
	center: latLng,
 	mapTypeId: 'osm'
});

map.mapTypes.set('osm', new OSMMapType());
map.setMapTypeId('osm');

So you you end up with something like this: image

Wednesday, March 30, 2011

jsOAuth turns 1 in April

On April 2nd, jsOAuth, the javascript OAuth library, will finally have it’s first stable release, bringing the library out of perpetual beta and into the realms of the big boys.

jsOAuth works with Appcelerator Titanium, node.js, CommonJS, Samsung Smart Tv’s and many other platforms that use javascript.
One library and one API to use everywhere your app is designed to run.

With a stable API you’ll now be able to build applications without worry that API changes will break your code.

I’m committed to making a great library and getting to this stable release has been a long time in the making. The project started early November 2009, with renewed interest in late October 2010 and has had a couple of key contributions from Steffen Schröder, Max Ogden and several from Łukasz Korecki. All these people saw potential in jsOAuth’s simplicity and have helped shape javascript OAuth for the future.

What if you spot something is missing? Let me know and I’ll get it in and tested as quickly as I can.

https://github.com/bytespider/jsOAuth
Monday, March 14, 2011

Authorize / De-Authorize API

I’ve been having some devising a suitable Authorize / De-authorize API. The problem stems from the complexity of the OAuth dance. See http://oauth.googlecode.com/svn/spec/core/1.0/diagram.png.

Ideally jsOAuth would have one entry point:

oauth.authorize(function successCallback() {
},function failureCallback() {
});

With jsOAuth as it currently stands, you would do something similar to this:

oauth.get('http://example.com/oauth/request_token',
    // success
    function(data) {
        console.info(data);
        var window = openURL('http://example.com/oauth/authorize?'+data.text);
        var requestParams = data.text
        window.onclose = function () {
            var pin = showPinDialog();
            oauth.get('http://example.com/oauth/access_tokenoauth_verifier='
                +pin+'&'+requestParams, function(data) {
                    console.info(data);
                    accessParams = parseTokenRequest(data.text);
                    oauth.setAccessToken([
                        accessParams.oauth_token,
                        accessParams.oauth_token_secret
                    ]);
                },
                // fail!
                function(data) { console.error(data) }
            )
         }
     },
     // fail!
     function(data) { console.error(data) }
);

I believe this is a user-space operation as each application may wish to implement this differently. If you look at the example above, its very difficult to break up the common parts into reusable code, whilst maintaining simplicity and allowing the application to implement the UI.

So onto the main reason for this post. How would you do it? What suggestions can you offer to help create a simple yet usable API?

Thursday, February 17, 2011

Custom Array-like objects

function Collection() {
	var i = 0, len = arguments.length;
	if (len == 1 && typeof arguments[0] == 'number') {
		for (i; i < arguments[0]; ++i) {
			this[i];
		}
	} else {
		for (i; i < len; ++i) {
			this[i] = arguments[i];
		}
	}
	
	this.length = i;
}

Collection.prototype = new Array();
Collection.prototype.constructor = Collection;
Collection.prototype.toString = function () {return this.join()};

var arr = new Array(6);
var dc = new Collection(6);

arr.push('test');
dc.push('test');

console.debug(arr, 'Array');
console.debug(dc, 'Collection');

So far this is working in Chrome 9, Safari 5 and Firefox 3.6. I’ll update this as I test each new browser, biut it’s safe to say it wont work in IE6

Thursday, February 3, 2011

Tutorial: Building a Twitter client with Appcelerator Titanium & jsOAuth - Part 2

Back in Part1 we started to build a alert based twitter client using jsOAuth, a Javascript OAuth library and Appcelerator Titanium, a platform for making applications using web technologies.

In this part, we’ll add better notifications, using Growl, libNotify or Snarl and add a timer to fetch new tweets every 1 minute.

Titanium Notifications

Using the Titanium Notification module we get better looking notifications that come from the system. On OSx Growl is used, On linux libNotify and on Windows Snarl. All will fall back to a basic built in notification system if you don’t have any of those notification systems installed.

To create a notification we need to call Titanium.Notification.createNotification() and then set each of the notification properties. With this we can update our code as follows.

timeline.forEach(function  (element){
  var notice = Titanium.Notification.createNotification();
  notice.setTitle(element.user.name);
  notice.setMessage(element.text);
  notice.setTimeout(1000);
  notice.show();
});

The code is fairly straight forward, we set the title to the name of the person who made the tweet, the message body to the tweet status and then set the notification to display for 1 second (1000 milliseconds).

If you run this code now, your screen will be filled with 20 tweets which clear after a second. This looks much better but a one off hit of statuses isn’t exactly useful.

Timers and tidbits

Next we should implement a timer to check for statuses every 60 seconds. This is done using the setTimeout() function.

Firstly, we need to wrap the body of our API call in a function, that we can call from the setTimeout function.

function updateTimeline() {
    oauth.get('http://api.twitter.com/1/statuses/home_timeline.json', success, failure);
}

At the top of our success() function, we add our timeout.

function success(data) {
    setTimeout(updateTimeline, 60000);
    
    /* ... */
}

Why do we do this? setTimeout executes a function after the specified delay meaning we could wrap the call in a conditional to prevent the next update. setInterval is a little harder to control because it calls the function every specified interval until we clearInterval.

If you ran this code, nothing would happen. That’s because we didnrsquo;t call updateTimeline() yet. Add the line after the updateTimeline decalration and then launch the app.

function updateTimeline() { /* ... */ }

updateTimeline();

I think you’ll agree, the app has just become far more uselful, but there is one think left. Every minute we get notifications of tweets we’ve already seen, which after a few minutes gets a little annoying. To solve this we can use the since_id parameter.

However, jsOAuth’s get method is a little limited in this version. Instead we’ll switch to the request method, which is far more flexible but more complicated to use.

/**
 * Makes an authenticated http request
 *
 * @param options {object}
 *      method {string} ['GET', 'POST', 'PUT', ...]
 *      url {string} A valid http(s) url
 *      data {object} A key value paired object of data
 *                      example: {'q':'foobar'}
 *                      for GET this will append a query string
 *      headers {object} A key value paired object of additional headers
 *      success {function} callback for a successful request
 *      failure {function} callback for a failed request
 */

As you can see, instead of passing separate parameters, we pass an object of key value pairs to set up the request. All the key names however reflect the naming convention of the get and post methods.

var sinceId = '';
function updateTimeline() {
	var params = {};
	if (sinceId != '') {
		params.since_id = sinceId;
	}

    oauth.request({
    	"method": "GET",
    	"url": "http://api.twitter.com/1/statuses/home_timeline.json", 
    	"data": params,
    	"success": success, 
    	"failure": failure
    });
}

updateTimeline();

The first 4 lines of the updateTimeline function check if we have a sinceId, and add it to the params object. This way we don’t get an invalid signature error from the Twitter API when it looks for the value.

However, at the moment we haven’t set the sinceId, we need to do this in the success() function. The Twitter API returns tweets with the latest at the top, by default. Using this knowledge, we can gleam off the first id and store it in the sinceId variable.

function success(data){
    setTimeout(updateTimeline, 3000);
              
    var timeline = JSON.parse(data.text);
    
    if (timeline.length > 0) {
    	if (sinceId == timeline[0].id) {
    		return;
    	}
        sinceId = timeline[0].id;
    }
    timeline.forEach(function (element){ /* ... */ });
}
Code completed

Launch the Titanium Developer tool and run your app. You’ll see the latest batch of 20 tweets but from then on you’ll only see new tweets until the next time you launch the app.

Growl notification

That’s all there is to it. In only a handful of extra lines of code, we’ve made the app more user friendly and useful.

To extend this app you could add a callback to the notification to allow replies or a menu item to allow posting of new statuses. The possibilities are great and Appcelerator Titanium makes it really easy to build applications quickly using technologies that most people are familiar with.

If you have any questions, comments or ideas on further expansion to this tutorial, please feel free to email or tweet me

Monday, January 31, 2011

Tutorial: Building a Twitter client with Appcelerator Titanium & jsOAuth - Part 1

This tutorial is intended to explain how to use Appcelerator Titanium with a javascript OAuth library, called jsOAuth, along with basic use of the Twitter API

Getting Started

You’ll need to download and install the Titanium Developer tool. There’s a great tutorial “Getting Started” on the Appcelerator Developer site. Feel free to skip this step if you already have the Developer tool installed and understand how it works.

Once you’ve followed that tutorial, set up a new project called “Growl Tweet Notifier” and continue this tutorial

jsOAuth and the Twitter API

jsOAuth was designed to be easy to learn and easy to use, as a result most of the heavy work is done for you. Hopefully you’ll agree how easy it is to use.

Download the latest version¹ of jsOAuth and put it into the Resources/ directory of your project.

downloading from github

You’ll need to reference the library in your project, so go ahead and place the following in your , and update the file reference as appropriate.

<script src="jsOAuth-0.7.5.1.min.js" type="text/javascript"></script>

In order to work with the Twitter API you’ll need to set up an app in the Twitter developer centre. Head on over to dev.twitter.com to register a new app. The form is fairly simple, but the crucial field is “Application Type” which need to be set to client. For the type of client we’re writing a “Default Access type” of Read-only will suffice.

Registering a new Twitter app

You’ll need to collect the consumer key and secret from the settings page presented after registration of your new app. They are under a heading called “OAuth 1.0a Settings”.

Twitter consumer key and secret

You’ll also need your personal access token. On the right of the settings page is a menu, you’ll need the “My Access Token” one. On that page, copy the key and the secret and you’re ready for some coding.

My Access TokenTwitter access token key and secret

As a side note, you should keep all tokens private, no one else should have access to them.

With all the keys and secrets to hand, you can instantiate an OAuth object.

var oauth = OAuth({
    consumerKey: "[YOUR-CONSUMER-KEY]",
    consumerSecret: "[YOUR-CONSUMER-SECRET]",
    accessTokenKey: "[YOUR-PERSONAL-TWITTER-ACCESS-TOKEN-KEY]",
    accessTokenSecret:"[YOUR-PERSONAL-TWITTER-ACCESS-TOKEN-SECRET]"
});

We’ll start with a basic call to the Twitter API, with a simple alert. Define a success function and a failure function to handle the responses from the API as follows:

function success(data){
    var timeline = JSON.parse(data.text);
    timeline.forEach(function (element){
        alert(element.text);
    });
}

function failure(data) {
    alert("Throw rotten fruit, something failed");
}

As you can see, both functions have a single argument data, to which jsOAuth will pass an object containing the response text, response headers and request headers.

Reading the Twitter API documentation, we know that a url with the extension .json will return a JSON response, so we JSON.parse() the response text held in data.text. The result is an array of tweet objects we can forEach over and alert out the status for.

Titanium has a build in JSON library, so the JSON helper is always available to us when we need to parse() or stringify() JSON data.

Finally we need to call the Twitter API end point, and pass the data to our callback functions. With jsOAuth a simple get request is as easy as:

oauth.get(URL, successCallback, failureCallback);

So plugging in our callbacks and home timeline URL we get:

oauth.get("http://api.twitter.com/1/statuses/home_timeline.json", success, failure);
Complete code preview

Now, we need to run the code using the Titanum developer tool. Load the tool, click your project and then click the “Test & Package” tab. Here you find a button to launch and kill your app.

Go ahead click launch and your app will run, query the Twitter home timeline API finally alerting each tweet.

Titanium developer launch

You’ll probably agree, that alerting out the last 20 tweets each time the application runs isn’t exactly useful. We could use a timer to call the API every few minutes. We could possibly use the since_id parameter to only get new tweets. We could also use Titanium’s notification module to get pretty notifications.

That’s all for this part of the tutorial. Next time, we’ll replace the alert with notifications, and set up a timer to collect only the latest tweets every minute.

Building a Twitter client with Appcelerator Titanium & jsOAuth - Part 2

¹ At the time of writing the current version was 0.7.5.2

Tuesday, January 18, 2011

Appcelerator Titanium: Bullet-Proof window drag

UPDATED: 2010-01-24
/*
Bullet Proof window drag

This is the most performant window dragging code
I could come up with. All the example on
developer.appcelerator.com we laggy

Version 2: More contained version
*/

var toolbarHandle = document.getElementById('toolbar');

toolbarHandle.addEventListener('mousedown', function (e){
    var isDragging = true;
    var mousePosition = {x:event.clientX, y:event.clientY};
    
    document.addEventListener('mousemove', drag, false);
    document.addEventListener('mouseup', function (e){
        document.removeEventListener('mousemove', drag, false);
        document.removeEventListener('mouseup', arguments.callee, false);
    }, false);


    function drag(event) {
        var wnd = Titanium.UI.currentWindow;
        var curentPosition = {x:wnd.getX(), y:wnd.getY()};
        
        curentPosition.x += event.clientX - mousePosition.x;
        curentPosition.y += event.clientY - mousePosition.y;
        wnd.moveTo(curentPosition.x, curentPosition.y);
    }
}, false);

You can find the code on Github