I'm building a mobile app with Backbone.js and I need to do a two-legged OAuth to connect with a REST API. I found a library called jsOAuth but not sure how to integrate it with Backbone.
Should I rewrite the sync method to include the headers?
Any help would be appreciated.
I was able to do this without using jsOAuth. I overrode my model's sync
method to make jquery ajax calls, and set the beforeSend attribute on those calls to create an oauth header on the request. Then, after setting the appropriate attributes on the model (body and url, specifically), all you have to do to PUT/POST is modelInstance.save()
, and the model takes care of the oauth itself.
The below examples are in coffeescript.
Backbone.Model.extend
sync: (method, model, options) ->
switch method
when "create"
$.ajax({
url: model.url()
data: model.body
dataType: 'json'
cache: false
type: 'POST'
beforeSend: (xhr, settings) =>
auth = @makeAuthHeader(key, secret, settings.url, 'POST', realm)
xhr.setRequestHeader('Authorization', auth)
xhr.setRequestHeader('Content-Type', 'application/json')
success: (data, textStatus) ->
model.postSuccess(data, textStatus)
error: (e, jqxhr, exception) ->
model.postError(e, jqxhr, exception)
})
when "update"
$.ajax({
url: model.url()
data: model.body
…
makeAuthHeader: (key, secret, encodedurl, method, realm) ->
accessor = {consumerSecret: secret, tokenSecret: ""}
message = {action: encodedurl, method: method, parameters: [["oauth_version", "1.0"],["oauth_consumer_key", key]]}
OAuth.setTimestampAndNonce(message)
OAuth.SignatureMethod.sign(message, accessor)
return OAuth.getAuthorizationHeader(realm, message['parameters'])
The oauth module I used is the one Netflix created in 2008, which you can find here. In case that gets taken down somehow, you can probably find the file by googling javascript oauth "This isn't as useful as you might hope"
. That query maybe doesn't sound like an endorsement of the file, but I found it to be untrue: the file is very useful.
url
function on it that returns the URL to send the request to.key
, secret
, and realm
get passed in to the initialize method of this model, and so are accessible in the code I've shown above.model.body
is an attribute you'll have to set yourself. It's not a backbone-standard attribute.success
method calls model.success()
. If this model had been a one-off, the ajax call's success
method would actually perform the success work right there.I think I may have answered this one on Twitter.
jsOAuth 1.x cant be plugged into jQuery easily and so therefore backbone. However there has been some progress since my answer on Twitter.
jsOAuth 2.0, in development, implements a XHR like interface so that you could use it like this:
jQuery.ajaxSettings.xhr = function () {
var xhr = new OAuthRequest;
xhr.consumerKey = consumerKey;
xhr.consumerSecret = consumerSecret;
xhr.accessTokenKey = accessTokenKey;
xhr.accessTokenSecret = accessTokenSecret;
return xhr;
};
As you can see, pushed directly into jQuery as the XHR object it uses.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With