Archive for June, 2012

etsy oauth in node

Saturday, June 30th, 2012

If you take one thing from this post, let it be: never believe anyone who says, “Oh, it’s easy, you just use OAuth.” I say this because we were in a meeting talking about how developers in the JavaScript hackathon I’m at today would authenticate to Etsy’s API and someone, looking at the docs, made a similar statement. What I’m sure he meant was, “Oh, it’s easy, you just use this OAuth library.” The library in question, however, is in PHP. Luckily, there are similar libraries for Node, but they don’t work exactly the same and no one had actually written sample code to let developers use them easily in their projects.

In the past, I’ve dealt with OAuth by using Everyauth, which is awesome when it works. However, the past couple days when I looking into this, it did not work. I forked the project and ran npm install and discovered several problems (possibly because I’m using 0.8.0). I tried to get around them and create an Everyauth module for Etsy anyway, but I couldn’t get the damned thing tested so, though it looks right, I may never know if actually functions.

Everyauth is just a robust, consistent wrapper around another oauth module, however, so I didn’t have to code the back and forth and passing of tokens and all the nonsense entirely manually. (Which I started to do before I realized I don’t really have anything I need to punish myself for.) It was actually pretty simple to fix up a module using that to abstract the flow of getting the authentication token from Etsy, and probably would be the same for your site (assuming your site isn’t OAuth2 cause then I don’t even know).

create a skeleton module and make an oauth object

I actually started with all this crap in the server.js file and then moved it into a module once I knew it worked. Don’t tell anyone. But when I did that second, responsible step, this is what the module file looked like:

var oauth = require("oauth").OAuth;

var etsyAuth = function etsyAuth( key, secret, domain, callback ) {

    var that = this;

    return this;
};

module.exports = etsyAuth;

I guess that’s a pretty lazy module, but this is an academic exercise, and it gets the job done. The thing to note is that the only real setup necessary is including the OAuth module. That allows us to instantiate an OAuth object:

    this.o = new oauth(
        "http://openapi.etsy.com/v2/oauth/request_token",
        "http://openapi.etsy.com/v2/oauth/access_token",
        key,
        secret,
        "1.0",
        domain + ( callback || "/auth/etsy/callback" ),
        "HMAC-SHA1"
    );

Since this only has to work for Etsy, not every API under the sun, the host URLs can be hard-coded right in there, as well as most of the other initialization settings. The consuming app will obviously need to supply its own credentials, and might optionally change the route the application should redirect to once it receives the access token, but those are the only customizations offered. Well, that and the domain, but only because there might be some weird fuckers out there who intend to move their apps off of local.host:3000 at some point.

consume the oauth module

It probably makes sense to look at how this gets implemented. I used Express, but mostly just for easy session management. Aside from the routes, this server just imports Express and the OAuth code I wrote and instantiates and configures the Express app and the OAuth object:

var express = require( "express" ),
    etsyAuth = require( "./lib/etsy-auth" );

var app = express.createServer(),
    api_key = "your key here",
    api_secret = "your secret here",
    entry = "/auth/etsy",
    callback = "/auth/etsy/callback",
    o = new etsyAuth(
        api_key,
        api_secret,
        "http://local.host:3754",
        callback
    );

app.configure( function(){
  app.use( express.cookieParser() );
  app.use( express.session( { secret: "example secret" } ) );
  app.use( app.router );
  app.use( express.static( __dirname + "/public" ) );
});

This has all been sort of copying Everyauth, but it diverges a little bit at the routes cause I feel like entry and callback routes are really a part of your application, and OAuth is just a thing that happens there. So the app creates those, and passes control to the OAuth module within the request handlers:

app.get( entry, function( req, res ) {
    o.getRequestToken( req, res );
});
app.get( callback, function( req, res ) {
    o.getAccessToken( req, res, function ( req, res ) {
        res.redirect( "/success.html" );
    });
});

app.listen( 3754 );

In this case, the request handlers are both stupidly simple, but they could be doing data transformations, conditional templates, or generating Fibonacci sequences – whatever fits the needs of the application. They call two functions that are properties of our OAuth object, and the final bits of code I implemented/moved.

get some tokens

The first function, getRequestToken, uses the URL we provided when the OAuth object was instantiated and our API key to request a token, which is saved to the session object. Then the response redirects to a custom URL sent back where the user will approve our request to operate on their behalf:

    this.getRequestToken = function getRequestToken( req, res ) {
        that.o.getOAuthRequestToken( function( err, token, token_secret, results ){
            if ( err ) {
                console.log( err );
            } else {
                req.session.oauth = {};
                req.session.oauth.token = token;
                req.session.oauth.token_secret = token_secret;
                res.redirect( results[ "login_url" ] );
            }
        });
    };

The next function is called once the user clicks the big “Authorize” button and comes back to the callback route in our app. It uses our existing request token and the verifier to get an access token, which gets saved to the session like the request token. If the application passed in a callback, we go ahead and execute that, and we’re done:

    this.getAccessToken = function getAccessToken( req, res, callback ) {
        if ( req.session.oauth ) {
            req.session.oauth.verifier = req.query.oauth_verifier;
            var auth = req.session.oauth;
            that.o.getOAuthAccessToken(
                auth.token,
                auth.token_secret,
                auth.verifier, 
                function( err, token, token_secret, results ){
                    if ( err ){
                        console.log( err );
                    } else {
                        req.session.oauth.access_token = token;
                        req.session.oauth.access_token_secret = token_secret;
                        if ( callback ) callback.call( this, req, res );
                    }
                }
            );
        }
    };

If you want to see how it all comes together, it’s on github. Hopefully that’s useful if you need to authenticate to Etsy or setup OAuth for your own API.

ladies, speaking

Saturday, June 16th, 2012

Between TXJS, which happened this week, and weareallaweso.me, it’s a good time to feel optimistic about women speaking at dev conferences. TXJS had something like six women speak out of sixteen speakers, which is a more impressive ratio than any other conference I’ve been to, and weareallaweso.me is trying to collect ways to make that a more common occurrence. Not too shabby, web developers. It seemed like a good time to reflect on the difference female speakers make, and maybe a little bit about how a female speaker might differ from a male one.

Obviously this is just my own observation and YMMV and all that, but seeing women speak is a big thing for me. And TXJS this year made me aware that’s it’s not only seeing women speak. Seeing them speak about their own projects and their motivations for their code makes me feel like open source is something I can do. That might sound disingenuous coming from someone who has participated a little bit in open source and has some of her own very small projects, but I am 100% serious about it and it was 100% needed. Watching women discuss projects that aren’t necessarily the biggest deal on github or used by everyone, but are nonetheless rigorous, important, and awesome made me feel like I can do those kinds of things too. I’d worry about leaning too far toward sexism in postulating as to why, but it’s different than seeing men do the same thing, and not just because I shared a gender with these speakers.

Actually, fuck it, let’s go ahead and postulate. While individual women are obviously as different as individual men, we do talk about how companies and industries can benefit from a more “feminine” way of conducting themselves. This means values that we associate with women and expect to see rewarded more in girls than in boys. Things like modesty, sharing credit, listening well and talking only when there’s something important to say, and sublimating our competitive drives when it’s to the benefit of a larger group. Things that we consider feminine traits are, broadly, things that place groups before individuals.

That’s what was so inspiring about these talks I saw. These women needed to solve real problems, so they quietly stepped up and filled that role of project maintainer when they created these projects. On larger projects, that role is almost always a man. Not only are these women capable of being brilliant developers (hopefully no one really needs proof of that anymore), but they’re capable of doing things women are often raised to leave to the boys. I was also struck by the way they spoke about their code, though. There was so little hyperbole, no sweeping dogma or expectations that the audience would automatically see why these projects were so cool. They carefully explained, and focused on the technical aspects. I can’t really explain it perfectly. It felt different. More academic. Less like someone was selling me something. Certainly I’ve seen men talk about their work this way, as well, but not very many. What would be really amazing would be if these speakers had inspired not just another woman with their approach to development and open source, but the men in the audience, as well.

With all that said, I found one thing wanting, and that was the technical nitty-gritty. While I loved seeing these women defend their work and think that happens in our communities all too rarely, I also wanted to see the code. I wanted them to scare me with their brilliance, and wow me with their code, and talk about how the use of this loop here instead of this switch there made all the difference in the world.

I know one of the things TXJS did to get so many ladies on stage was to invite less experienced speakers. That’s crucial for seeing more female speakers and changing gender diversity in general, because Rebecca Murphey and Lea Verou can’t be everywhere at once. I hope to see more of this, but I hope that conferences will coach these greener speakers, as well. It would be wonderful for conferences to send out a detailed sketch of their audience, even if it’s just the organizers’ best guess. (This would probably help female attendees feel more comfortable, too.) I think knowing that there will be people in the audience who’ve been to ten or more JavaScript conferences, for example, would make me feel more comfortable showing tons and tons of code, whereas if I thought the audience was likely to have only 1-2 years experience I’d want to talk more generally and limit the amount of code I showed. This only came up for me because I was dying to see these ladies’ code and I think last year when I spoke at TXJS I made a mistake in speaking too generally because I’d attended the conference as a serious-JS-n00b the year before. I can see how that cycle might kind of perpetuate itself without intervention from the organizers to get people to promote content at a certain level of detail. Standard disclaimer about having never organized a conference, though.

I hope people feel that coaching is worthwhile. Speaking from personal experience, it can be difficult to find the confidence to speak about something you’re still learning yourself, and even more difficult to feel like your own work is interesting. Knowing not just what to submit or prepare talks on, but what aspects to discuss and who to target the content to could potentially make a huge difference in getting new women speakers onto conference stages. Or maybe not. But bravo to the organizers of TXJS and all their speakers (male and female), and to the folks behind weareallaweso.me. I hope these are signs of more good things to come.

answering the wrong question?

Sunday, June 3rd, 2012

It seems like there’s a really good opportunity for someone to do something very helpful and make a site that compares and tracks JS frameworks. As far as I can tell, though, no one has, so maybe I can be excused for my ignorance if what I’m looking for already exists. What I’m looking for is a framework that deals with webpages as webpages, and deals with elements within an application as elements.

I kind of go back and forth on my feelings about MVC, but they average out right around apathetic skepticism, or ::rolleyes:: if you want. It’s because there are a shit-ton of them and MVC is pretty easy to write code for, cause things have these very clean relationships. That’s great for your data, it’s great for your backend, yada yada yada. But it’s pretty much shit for complicated interfaces. Views and models don’t always line up. Views without models exist and still have state. Some states are important to the application, some are important to a given object, some are important only to a widget. You can shove all the shit on your page into the MVC idiom – and people do – in order to use an MVC framework, but I don’t think that solves the real problem.

If you know of a framework that’s primary concern is with organizing DOM elements and DOM interactions, please stop right now and go down to the bottom and leave a comment telling me about it. As far as I know, such a thing doesn’t exist. jQuery’s great for working with the DOM, of course, but doesn’t make any attempts at organizing things or offering a hierarchy of objects. We now consider DOM interaction a bad thing, so more “serious” frameworks tend to shove the DOM stuff under the rug, deigning to interact with the page only when necessary.

I don’t want to say a bunch of shit I’ve said before here, but that’s just fucking silly. Structuring your code around abstract objects instead of the mechanisms by which things are actually made available and manipulated – DOM elements – is like having a perfectly organized closet while the rest of your house looks like something from the TV show Hoarders. It’s low-hanging fruit, and it skirts the issue that’s the most difficult to deal with and the most inseparable from the idea of a web application.

I’ve looked at a bunch of these frameworks. I’m not going to lie, I’ve only attempted to write apps using a few, and quickly got frustrated by the tradeoffs between limitations and simplifications they were offering. You don’t have to agree, but I’m just saying: I’m a computer science major, one of not very many I know, and I find their approaches way too computer science-y. Writing an interface programmatically is one of the most painful things I’ve ever had to do (repeatedly, in VB), and that’s what the frameworks I’ve worked with all devolve to once you’re beyond the tidy CRUD model where MVC can give you genuine shortcuts. But, again, I’d love to know if I’m missing something.

I read a blog post about how fashion designers should learn to code recently and was kind of horrified by it. To me, it’s a perfectly example of why not everyone should learn to code. Not because the solution was bad – I think polaroids are about as elegant as you’re gonna get, personally – but because part of how a programmer has to train himself or herself to think is this kind of obsessive, examine the problem from every angle, think of every possible optimization pattern. We do need people who can think that way within certain contexts. It’s useful when you’re building an application. Or, say, a JavaScript framework. But it can and does bite us. We know what happens when we’re wandering around unchecked with a hammer looking for things to use it on. (We use it inappropriately.) I feel like it’s time to stop letting classical CS patterns inform the way we build JS frameworks and embrace the way the DOM actually works and is used and has been used, and build around that. When someone truly does that well, I think JavaScript will take another big leap forward, and we’ll all wonder why it took so long for us to address the right problem.