Cross-site Authentication in the World of APIs

posted by chip on Tuesday, the first of May 2012, at a quarter till one in the morning
It used to be that some HTML displayed by your browser was the beginning and end of a website. Nowadays, with the ever expanding mobile world and the apps that go with it, it's just as important to have an interface built for machines in addition to the one built for humans. The API has become a staple feature of our modern web, and with it brings a new set of challenges for authorizing and authenticating users.

If you're a frequent reader, you'll know that I'm a pretty big fan of OpenID. But while working on some of my newer projects (notably Blërg), I realized that I couldn't really use OpenID authentication for the web APIs. The problem is that OpenID relies on working in the context of a browser. It redirects you to a webpage which authenticates you and redirects back. That obviously won't work if your endpoint is expected to return JSON. I've had grand designs of making all of The Dominion of Awesome work with OpenID for some time now, but as APIs become more and more a part of my projects, I'm going to have to leave it behind. I really believe in both OpenID and the utility of web APIs, so this was a really unfortunate choice for me.

As near as I can tell, there's no good "universal authentication" method for web APIs. There is OAuth, but it's designed for a wholly different purpose. OAuth allows a website to authorize a remote user to use its resources. It's not designed to provide authentication. You can use it to provide a "pseudo-authentication" service where the resource is the user's account information. OAuth can't work as a generic authentication service in this way though because the consumer application has to first get an API key and secret from the site providing authorization. This means I could authenticate against a specific service (like say, Twitter), but I couldn't allow users to authenticate with a service of their choice like you can with OpenID.

So the best you can do for now is to create your little enclave, and if it gets popular enough, other people can use you for API authentication if they ask nicely. Lots of sites are doing this now with Twitter or Facebook authentication. This is unfortunate because it means that while there's a huge breadth of applications and experiences on the web now, control over your identity is increasingly becoming the domain of only a few large entities. Where OpenID provided more freedom and options for users to choose their identity service, the need for APIs and the rise of OAuth is creating the opposite effect.

Where do we go from here, then? Well, the OpenID folks are working on a non-browser API called OpenID Connect. It's still very much a draft, so who knows when or if we'll see websites start to adopt it. Personally, I think I'll just stick with the tried and true method — use plain username and password-based authentication, and make management of credentials the user's problem. Hopefully OpenID Connect will come around just in time for something else to disrupt the Web as we know it. :-/

0 comments reply permalink

On the Buddha Nature of APIs

posted by chip on Monday, the twenty-third of April 2012, at two in the morning
I've been working on rewriting Blërg in Enyo 2.0. It's forced me to think a lot about code reorganization and encapsulation of functionality, which is great. Enyo encourages encapsulation by giving you a flexible object model and generic event handling, but there's one sticky point that doesn't encapsulate well: the API object.

Particularly in the case of APIs involving authentication, an API object needs to keep some kind of state global to the application. Just as critically, an API has to be accessible from many different (and distinctly encapsulated) parts of an application. How do you balance these opposing needs? Or more to the point, how do you balance these opposing needs without doing something that software designers will frown upon?

A Meditation

First, some background on Enyo 2. Enyo classes are called 'kinds', and are defined with an anonymous object full of properties specifying functions, data, and behaviors. It combines functionality and object hierarchy into a single declaration.

Enyo extends the HTML DOM event model to allow the sending and handling of generic events. Events can also carry arbitrary data, making it a kind of message passing system that moves messages up and down an object hierarchy. To send an event up the hierarchy, you 'bubble'.

this.bubble('onDoSomething', {data: "stuff"});

And likewise, to send an event to all your children, you 'waterfall'.

this.waterfall('onDoSomething', {data: "stuff"});

With these, you can have objects send messages to other parts of the code without knowing where those parts are. For example, I have a login widget that bubbles a 'onTryLogin' event to the main object, which makes an API call and waterfalls the result (an 'onLogin' or 'onLogout' event) so that any object in the application can react appropriately. That last bit is really sweet — it completely decouples the UI changes for logout and login from the actual logic.

Events are handled in one of two ways. The first is to directly specify a handler function. This handles any events generated from the object or its children.

{kind: "onyx.Button", content: "Login", onclick: "trySomething"}

This handles a click event by running the trySomething function in the current object. (Event names that derive from DOM events are lower case. Generic events use camelCase.)

The other is to specify a handlers object in your object definition. This handles any events from your object or its children.

enyo.create({
    name: "MyObject",
    kind: "Component",
    handlers: {
        onDoSomething: "trySomething"
    },
    components: [
        // Any of these sending 'onDoSomething' will
        // be handled by 'trySomething'
    ]
});

A Koan

So back to our poser. How do we create an API object with global state but proper encapsulation? Well, the first obvious solution most of us come up with is to simply create a single instance and make it global. But that's not terribly elegant, and in slavish adherence to OOP style, you decide to instead make it a member of your "root" class, then pass it around to all the objects that need it. You go to bed at night knowing that your CS225 teacher won't yell at you for using a global object, but deep in that niggling contrary part of your brain, you know that the object merry-go-round you've created isn't very clean and it'll be a pain to maintain. But it works.

Then JavaScript's asynchronous nature throws a wrench in the works. I could make all the API functions take success/failure callbacks, but I'd really like to use Enyo's slick event system. Many separate objects in the application would like to get events from the API, but there's only one API object. Making it global or passing it around doesn't help, either, because Enyo 2 does not currently expose a way to add event handlers at runtime (which is honestly pretty silly).

Well, the first thing I came up with was and elaborate event routing system. The object bubbles a service request event, which reaches the main object, which passes the request on to the API object. The API object bubbles the response, which reaches the main object, which is waterfalled down and eventually makes it back to the requesting object. Beyond the obvious inefficiencies, it becomes a hot potato nightmare of event passing. You need four functions in the main class just to route events, plus at least three event types! For one request! There has to be a better way.

The Middle Path

The solution I came up is the judicious use of static class data. Static class data doesn't get much respect, since it's pretty much the better dressed cousin of global data. But it's there because sometimes it makes sense. And here it very much makes sense.

So what you do is you put all the data that needs to be global in a statics section of your API object. The rest of your API is regular instance methods and data. Then you create an instance of the API object wherever you need it. Each instance has its own event handling, but the shared data is consistent across the application. Here's an example skeleton API class that shows what I'm talking about.

enyo.kind({
    name: "API",
    kind: "Component",
    statics: [
        sessionId: 0
    ],  
    getThing: function() {
        API.sessionID++;

        // This is typically asychronous, but because of event handling,
        // the result is the same either way.
        var response = makeRequest(API.sessionID);

        this.bubble('onThing', {thing: response});
    }
});

Note that the static data is accessed by using the kind name instead of this. Static data doesn't live in your instance, it lives in the global kind object (which is very much like a constructor function in the classical JS object system). Then, in some object elsewhere, you add the API object and use it.

enyo.kind({
    name: "Application",
    kind: "Control",
    components: [
        {kind: "Button", content: "Get Thing", onclick: "getThingClick"},
        {name: "api", kind: "API", onThing: "processThing"}
    ],
    getThingClick: function() {
        this.$.api.getThing();
    },
    processThing: function(inSender, inEvent) {
        // We now have our thing in inEvent.thing
    }
});

Which is pretty darn clean, at least from the API user's perspective. Hopefully it doesn't keep anyone up at night. And in the case of web programming, you already have global state like cookies or the window object, so you're damned from the start. I hope this was enlightening for someone. :)

0 comments reply permalink

Beatrice Shepard, Galactic Badass

posted by chip on Friday, the thirteenth of April 2012, at four in the morning
You may know some stories surrounding Commander Shepard. But how well do you really know the legendary Commander? You probably think her name is John or Jane, but you're wrong. Allow me to introduce to you...

Beatrice Shepard.

Beatrice Shepard fought off the Reapers, but she wasn't happy about it. She'd just as soon stay out of it if it didn't mean the end of all civilization. Here are some more facts you probably didn't know about Beatrice Shepard:

Ain't nobody fucks with Beatrice Shepard. Nobody.

0 comments reply permalink

Forza 4 Pals: Fugly Ford Ka

posted by chip on Friday, the twenty-third of March 2012, at four in the morning
When I told Erickson about my superpowered Datsun 510, he immediately thought about doing the same thing to the Ford Pinto. The Pinto has the lowest Performance Index in the game at a measly 100. Unfortunately, the Pinto is a DLC car, so he got the next best thing: the Ford Ka. It also shares the pitiful 100 PI rating, and like the 510, it can be tuned through the roof.

After heavy tuning, Erickson gave it a paint job that I can only describe as "cringeworthy". It's like the car was the bukakke recipient at a pastel teletubby orgy. Pink, purple, green, blue, and a splatter of reddish brown make a patchwork horror of light and color that is somehow made even more ridiculous by the red tow-hook tongue hanging out of the grille. When I asked him what possessed him to make such a design, he stated rather matter-of-factly, "Art designed to be unattractive like this is it's own calling."

Under the hood is a bored-out and twin-turbo'd 2.8L Ford Focus engine good for 531HP. All that power gets to the ground through an all-wheel-drive system ripped out of the Escort Cosworth. At just 2226 lbs, it gets off the line like a jackrabbit. And for having such a short wheelbase, the Ka is surprisingly pinned down. While there's always a little drama in such a highly strung car, the Ka is pretty much just point and shoot. The light weight and stiff suspension will get you in trouble though, if you're not careful.

Pronounced rumble strips tend to act like ramps, making the Ka fly off of them like the shiny chrome orb in a pinball machine. The edge between a perfect corner and screaming while you tumble end-over-end is a pretty thin one. In one race around the Nürburgring, Erickson managed to land it on his roof. I kindly went back to nudge him back on his wheels, but the car was pretty much shot at that point. Great fun, though. :)

Next up, we have a Volkswagen Rabbit GTI I call "Hot Dog" (Did I say it was a Golf? Same difference), and Alex bit the DLC bullet to put the Ford Pinto through its paces with explosive results! Don't touch that dial!

0 comments reply permalink

Forza 4 Pals: The Green Machine

posted by chip on Wednesday, the twenty-first of March 2012, at a quarter past five in the morning
Forza has always had a really good car modification system. In particular, they enable a range of engine and drivetrain swaps that allows for some truly spectacular creations. I've talked about my RWD CRX before. My friends and I at the Dominion of Awesome have been busy making our own little Frankensteins: the F-class supercar.

For the uninitiated, F-class is the lowest class in Forza. It's where you find such great cars as the Toyota Aygo or the Chevrolet Spark. Cars so unremarkable they don't even sell them in America. So I thought, "I wonder how far you could increase the performance on these? Could I get them into A class? Or beyond?"

The answer is yes. Very yes.

My first experiement was the Datsun 510. The 510 was a classic small two-box sedan in the late 60's and early 70's. It actually has a fair amount of racing history, so it shouldn't be too hard to soup it up. And it wasn't. Behold, the Green Machine.

The Green Machine sports a Skyline GT-R AWD drivetrain coupled to a SR20DET out of the S15 Silvia. This puts it well into the R3 class with over 700HP. Or, with a VQ35DE from the 350Z and a honking huge turbo, it puts out 767HP, getting it just barely into the R2 class. Tire smoke is the name of the game, and the Green Machine can play all day.

With a stab of the accelerator, the back end comes out and the Green machine will execute beautiful four wheel drifts. You can drive it fast or drive it sideways. It's an easy choice for me. :)

Stay tuned for more. Later I'll be showing you the rest of the F-class supercars in the Dominion of Awesome's stable. Next up, we'll have a pink and purple Ford Ka, then later a VW Golf GTI that wants to be a hot dog, and a Ford Pinto that is "The Bomb".

0 comments reply permalink

Super Productive Weekend!

posted by chip on Tuesday, the thirteenth of March 2012, at a quarter till five in the morning
Alex went up to Chicago this weekend, leaving me to my own devices. Oh no, what do I do!?

I dunno, how about EVERYTHING?

I...

I think I've actually been starved for some "me time", so it was good to catch up with myself. The only downer is that I missed this year's Engineering Open House. :[

Now if you'll excuse me, I'm going to go for a drive because it's beautiful out.

0 comments reply permalink

(M)ass Effect

posted by chip on Saturday, the tenth of March 2012, at five in the morning
I went out to my parents' for some Swedish meatballs and games. I didn't want to pass up the opportunity to play Forza 4 in HD, so I packed up the game and threw the save up on XBox Live's cloud storage. That worked fine, but my parents' internet is so poor that it couldn't resync the save file to the Internet. Now that I'm home, I can't play my save because it hasn't synced. I'm probably going to have to go back to my parents' house and rescue the data with a USB drive.

But that's OK...

Because when I went home to my parents', I picked up a couple of other games I can play: Armored Core: for answer, and Mass Effect 2. AC4 is my brother's game, and ME2 was a gift from Nancy, who had a spare copy because she lent it out and didn't want to wait for it to be returned. I was just going to start there, but I'd played the ME3 demo and was so impressed with it that I bought the first Mass Effect so I can start from the beginning.

While I was playing, I thought... "There has to be a parody called Ass Effect. There just has to be." And, of course, there is. I'm sure if you tried just a little harder than I did, you could find something pornographic.

The game itself is excellent, but I'm sure I don't need to tell you that. If you haven't played it in the last five years, you probably don't care. Just go play it.

And speaking of videogames and sci-fi, Quantic Dream just released another stunning tech demo entitled Kara. It's only seven minutes long, but it's probably one of the best sci-fi short stories I've ever experienced — it gives me chills every time I watch it. If they make a game out of this concept (like they did with the Heavy Rain: The Casting), I want to play it. Badly.

1 comment reply permalink

A "New" Idea

posted by chip on Tuesday, the twenty-eighth of February 2012, at a quarter till six in the morning
I just had the most wonderful idea for a simple UNIXy notification system. Back to basics — the simplest way of storing a list of items is a directory of files. So the events are actually text files, probably organized with some metadata about the notification's origin, possible actions, etc. Then you have a program that notifies you when new files are added, and one to let you read and delete them, and you're golden.

But you don't have to stop there. You could create a daemon that can accept notifications over the network and store them in your notification directory. Then you can get notifications from other machines like your phone or even a web service.

...

Oh dear, it seems I've reinvented the UNIX mail system. :-/

0 comments reply permalink

Gaming on the Other Side

posted by chip on Monday, the twenty-seventh of February 2012, at a quarter past four in the morning
So I recently purchased an Xbox 360. I'd been eyeing one since Forza 4 came out. I can't exactly cite anything about Forza 4 that makes it superior to GT5, but it is still a very solid racing game. At nearly the same time, my friends Alex and Erickson got 360s, so we've been occasionally playing together. It's nice, but I can't say I really like the 360. I don't really like the PS3, either. The purchase was more of a matter of peer pressure and weighing which choice was least terrible.

I've played on both the 360 and the PS3, and IMNSHO, they're both flawed. They're both game systems with services attached. You can watch Netflix and Youtube. Each has an online game store, each has multiplayer services, and each have compelling console exclusives. That's cool, but it's not really enough for me. I've long been a member of the Glorious PC Gaming Master Race , and the tradeoffs made on both the 360 and the PS3 seem arbitrary and frustrating. The 360 is trying so desperately not to be a PC even though Microsoft clearly could make it feature-equivalent, and the PS3 is so desperately trying to be a PC but Sony won't commit because they're afraid of PC-style piracy (and what they do have is rather poorly implemented). So, in a competition for which system is the best at providing features I want, they both lose.

The real crux of the decision is the fact that while both Microsoft and Sony are providing a frustratingly locked-down consumer-only system, Microsoft is at least competent enough to not have their online service wholesale cracked into and user information stolen (but it seems that something is rotten in Redmond). Sony clearly does not give a shit about their users.

The Forza/GT comparison is also interesting. I've spent considerable time playing both now, and I'd like to state for the record that both series are absolutely wonderful. In my mind, there's not really a competition between them. If you're really a car nut, you'd be silly not to play both. That's usually impractical, though, so you should just get whichever one is on your system, because you're going to be happy either way. Which is not to say they don't have their differences. From outside the automotive simulation genre, they look like near perfect copies, but like any finely crafted product, the important differences are always in the details.

Forza's focus is pretty strictly on racing. The breadth of events and types has grown over the years, but Forza's bread and butter is still the circuit race. Forza 4 has only strengthened this position. The original Forza had night tracks, but Forza 2 lost them. Forza 3 held on to the New York City circuit, but it too has disappeared in Forza 4. With only a few exceptions, all of Forza 4's tracks are racing circuits. And they're all daytime courses in dry conditions -- there's no nighttime races, nor any races in rain, snow, or off-road. Forza also has a very detailed focus on car modification. Forza allows extensive and detailed changes, as well as engine swaps, aspiration conversions, and even drivetrain swaps. Car customization goes even further with paint and decals to change the look of your car.

Gran Turismo, on the other hand, is all about the experience of driving. The cars look slightly better than Forza, and the environments look absolutely gorgeous. The course list in GT5 covers city courses, permanent circuits, and off-road venues. I personally think the track design for fictional courses in the GT series is superior to Forza. Many tracks support not only day/night, but also dynamic weather and daylight transitions. One particular challenge has you racing a rally course as dusk turns to night. As you're driving, the sky lights up with fireworks all around you. It's just a fantastic experience. The downside of GT is the limited amount of fully-modeled "premium" cars, which are only visually modifiable with paint colors you've unlocked, plus rims and wings. The performance modifications are rather generic and limited. Also, compared to Forza 3 and 4's heavily directed career mode, GT feels very open-ended, which can be frustrating when you're trying to find the right combination of car and performance tuning to go race. But despite all that, it's just amazing when it comes together.

So you see, they're both very different and both provide a worthwhile experience. I'm currently loving the perverse and twisted ways you can modify cars in Forza (ask me about the Datsun 510-R). Do I miss GT? Sure. But I do have GT1-4 that I can play on my PS2, and that is still a whole lot of game. I'll get around to it eventually, probably after Sony decides not to make the PS4.

1 comment reply permalink

Archives!

posted by chip on Saturday, the twenty-fifth of February 2012, at five in the afternoon
As promised in the previous post, I've made a new archives page which you can find in the navigation above (or to the side, or wherever I've put it now). It's organized by year, month, and day going back to 2003. Now you can easily browse all my cringeworthy emo bullshit from college! (Oh God Why...) I've also simplified the page navigation at the bottom so it's not a huge list of page numbers. Just next and previous now. Simple.

2 comments reply permalink

previous
All content printed on 100% recycled internet memes.