Chris Shiflett

Principal, OmniTI Inc.

Speaking at the following events:
 

Blog ()
This is syndicated content from http://shiflett.org/
 
[Tue, 17 Aug 2010 17:09:43 GMT]

For some time now, I've been happily using 1Password to manage all of my online accounts. I really like it and recommend it to all of my friends, but I do have a few reservations:

  • It uses a proprietary format for storing my account information. (Older versions used the Keychain format.)
  • It does not integrate with Mobile Safari or anything that's not a browser (e.g., iTunes). This means browsing on my iPhone or iPad is practically impossible, and my iTunes password has to be easy to type, leaving me vulnerable.
  • There's currently no way for developers to make sure their sites support 1Password. Given the way 1Password works, microformats seem like a possible solution.

Earlier this year, I heard about Account Manager, a new effort from Mozilla that aims to help web sites and users connect in a safe and consistent way. In other words, it can potentially make managing passwords online a lot easier, more consistent, and more secure. Furthermore, because it's being developed as an open standard, widespread support is a possibility.

The spec uses MediaWiki, which does not number sections by default. Because all references within the spec use section numbers, you might want to log in and select "auto-number headings" in your preferences. (You can also refer to the table of contents at the top.)

This weekend, I managed to find some time to explore Account Manager a bit. With the help of Dan Mills, I got it working with Firefox 4. He was also kind enough to provide some preview builds for you to use:

If you want to try it out before I give you a quick tour, install one of the Firefox 4 preview builds linked above, and visit my Account Manager demo.

Implementing Account Manager is pretty straightforward. To keep things simple, I'm only going to show you how to implement login and logout. Think of this as two steps:

  1. Inform the browser whether the user is logged in.
  2. Inform the browser how to log in and log out.

The first step is accomplished via the X-Account-Management-Status header. (This is a response header you can set with the header() function.) Here's an example:

X-Account-Management-Status: active; id="chris"; name="Chris Shiflett"; authmethod="username-password-form"

This header informs the browser that the user is currently logged in as chris. Instead of active (logged in), you may specify none (not logged in) or passive (remember me). The rest of the header is a semicolon-delimited list of attributes, three of which are currently defined: name, id, and authmethod. There are various options for authmethod, but I'm only going to be talking about username-password-form.

Informing the browser how to log in and log out is almost as easy. You indicate these things in an Account Management Control Document (AMCD). You can view my AMCD to get an idea of the format, but because json_encode() doesn't generate the most readable JSON, I'll share the PHP as well:

<?php
 
$json = array(
    'version' => 1,
    'sessionstatus' => array(
        'method' => 'GET',
        'path' => '/lab/account-manager/status'
    ),
    'auth-methods' => array(
        'username-password-form' => array (
            'connect' => array(
                'method' => 'POST',
                'path' => '/lab/account-manager/login',
                'params' => array(
                    'username' => 'username',
                    'password' => 'password'
                )
            ),
            'disconnect' => array(
                'method' => 'GET',
                'path' => '/lab/account-manager/logout'
            )
        )
    )
);
 
echo json_encode($json);
 
?>

Although it's not indicated in the spec yet, sessionstatus is now required. In a future post, I will discuss this in more detail along with registration and other features.

After you create your own AMCD, specify its location with a Link header:

Link: <http://shiflett.org/lab/account-manager/amcd>; rel="acct-mgmt"

As a reminder, you can try my demo of Account Manager. I encourage you to use something like Live HTTP Headers, so you can examine the HTTP traffic. If you want to implement Account Manager on your own sites, be prepared to make frequent changes.

Here are a few additional things I noticed:

  • Account Manager does not seem to abide by the Cache-Control header correctly, which can make development cumbersome. You must restart Firefox for any AMCD change to take effect. (See my comment below for an alternative solution.)
  • It is not currently possible to protect against CSRF, but there are ongoing discussions about it, so a solution is sure to come in the near future.
  • Logging out currently requires the GET request method. As I've discussed before, POST is more appropriate. Because Account Manager provides a consistent interface, the request method you choose to use has no aesthetic implications, so I hope most people will use POST.

Want to participate in a new browser technology that just might prove to be more important than tabs? Install Firefox 4 (Mac, Linux, Windows), read the spec, try my demo, join the mailing list, and most of all, have fun!

There's a lot I did not cover in this post, but I will be blogging more about Account Manager in the near future. One of the missing topics I'm most interested in exploring is how Account Manager can potentially be supported by apps other than Firefox. It's possible that 1Password could continue to be essential, because it could be the app-neutral data store for all of my account data.

Tue, 17 Aug 2010 17:09 GMT — Chris Shiflett’s Blog Chris Shiflett’s Feed

 
[Thu, 05 Aug 2010 14:31:35 GMT]

Yesterday on IRC, Andrei Zmievski mentioned a new song about PHP. Sean Coates linked to a YouTube video with the song, which I then mentioned on Twitter:

PHP finally has an anthem. This is what we’ve been lacking. http://j.mp/PHPanthem /via @coates

If you haven't listened yet, take a moment to do so. There are a few options:

The song is by Lee Fernandes, who goes by @reelfernandes on Twitter. I couldn't find the lyrics online, so I created a new document on TypeWith.me to solicit help. To my delight, prompted by Sean's request, Lee joined and helped us out. :-)

TypeWith.me is made with EtherPad software. Lee thinks it's excellent. If you're sad about yesterday's news about Wave, you should give it a try.

The complete lyrics are below, with some links to add context. Enjoy! :-)

Oh yeah. (Oh yeah.)
(Just one day it just hits you all of a sudden. It's just like...)

Oh yeah, I'm so PHP this year.
Got a mic in the left, and 'n the right, cold beer.
Compile that Apache.
Now we got version 5 and two chicks laid out in the back seat.
Yeah, sometimes the code looks a little trashy.
But, this ain't ColdFusion.
Stop talking sassy, and pull up them panties.

I'm really... I'm just saying; why don't you go check out the API reference docs.
They're really good.
(They are.)

Is it underline or CamelCase?
I can't remember; I've been busy poundin' cakes.
It's what PHP developers do.
We get more booty than you.
Don't be jealous when you smell us; check the Boolean dude, it reads...

[chorus]
(Oh yeah.)
Check the Boolean dude; it reads true.
(Oh yeah.)
PHP gets more booty than you.
(Oh yeah.)
Check the Boolean dude; it reads true.
(Oh yeah.)
PHP gets more booty than you.
(Oh yeah.)
Check the Boolean dude; it reads...

True, PHP gets more booty than you,
but we still keep it clean.
MySQL really real wrappin' all strings.
Filter input like it was a herpes strain.
(You know what I'm saying?)
That's why we got the STD class.
Objects we pass might need to be trashed.
Girl, what you doin'?

Come gunzip this.
Be my witness as I strip this string of all slashes.
Now, I got what I need.
No traversing my filesystem when you ain't supposed to be.
That's how it is rolling with PHP.
All the hot chicks, yeah, they love PHP.
(It's so true.)
(Oh yeah, that's what I'm talking about.)

[chorus]

(Yo, yo, tell 'em about it.)

PHP: Hypertext Preprocessor.
It's real out here.
Somebody better call the mod_security officer.
My concern is for those weak half-assed scripting languages.
The ones that can't hang with us.
It's strange, but they get hanged and remain in dust.
Some aren't quite dead and still remain a pain to us.

PHP's got more muscle.
In a nutshell, nothing's quite like it.

Predicted by the ancient cultures and the psychics.
The ones who dreamt in recursive states.
Whispering premonitions of open source community gates.
PHP.

(Oh yeah...)

[chorus]

If you're curious to learn more, you're in luck. Sean and Paul Reinheimer will be interviewing Lee for a future episode of Pique Web, their new podcast on PHP and related web technologies.

Oh yeah!

Thu, 05 Aug 2010 14:31 GMT — Chris Shiflett’s Blog Chris Shiflett’s Feed

 
[Thu, 29 Jul 2010 19:52:18 GMT]

We are currently working on an app that uses a number of technologies, including PHP, Python, and MongoDB. Recently, a need arose to use sequential identifiers for users, similar to an auto_increment column in MySQL.

If you've used MongoDB, you might be familiar with the default behavior of using a UUID as the primary key. This is convenient, especially if you partition your database across servers, because you don't have to coordinate the primary key in any way. If you use sequential identifiers (as I demonstrate in this post), you can use multiple servers and interleave identifiers by advancing each server's sequence by the total number of servers. (For example, with two servers, advance each sequence by two, so one server generates even identifiers, and the other generates odd.)

I'd rather not discuss the advantages and disadvantages of either approach, because it's exactly this debate that makes it very difficult to find any useful information on using sequential identifiers with MongoDB. Instead, I'm just going to explain how I did it, and hope this is helpful to someone. :-)

First, create a sequence collection that you can use to determine the next identifier in the sequence. The following creates a collection called seq that has a single sequence in it (for users), but you can add as many as you need:

db.seq.insert({"_id":"users", "seq":new NumberLong(1)});

If you assign seq to 1 instead of new NumberLong(1), it will be interpreted as a float due to a JavaScript quirk.

Before adding a new user, you need to increment the sequence by one and fetch the next identifier. Fortunately, the findandmodify() command provides an atomic way to do this. Using the MongoDB shell, the command would look something like this:

db.seq.findAndModify({
    query: {"_id":"users"},
    update: {$inc: {"seq":1}},
    new: true
});

Because I'm using Lithium, I added a method for fetching the next identifier to my User model:

<?php
 
namespace app\models;
 
class User extends \lithium\data\Model {
 
    static public function seq() {
        $seq = static::_connection()->connection->command(
            array('findandmodify' => 'seq',
                  'query' => array('_id' => 'users'),
                  'update' => array('$inc' => array('seq' => 1)),
                  'new' => TRUE
            )
        );
 
        return $seq['value']['seq'];
    }
 
}
 
?>

If you're not using Lithium, you can use the MongoDB class to execute a command().

With this in place, adding a new user is a simple process. I create an array called $data with everything I want to store for a user, and then do the following:

<?php
 
$user = User::create($data);
$user->_id = User::seq();
$success = $user->save();
 
?>

This example should be easy to adapt to any environment. Once you have the next identifier in the sequence, you simply store it as you would any other data.

I hope to blog more about both MongoDB and Lithium. As these technologies are still pretty new to me, please feel free to point out any improvements. I'll update the post accordingly.

Thu, 29 Jul 2010 19:52 GMT — Chris Shiflett’s Blog Chris Shiflett’s Feed

 
[Wed, 30 Jun 2010 22:12:40 GMT]

Change Blindness Experiment at the Dutch PHP Conference

Two weeks ago, I had the great honor of giving a keynote at the Dutch PHP Conference. Because I had never been to Amsterdam or to the Dutch PHP Conference, I was really excited to have a chance to speak there. It was also an opportunity to give my favorite talk to a new audience.

On the morning of the keynote, I followed along with conference organizer Lorna Mitchell to the RAI Center where the conference was being held. As soon as I saw the stage, I smiled. Not only would I be able to stand on a stage unobstructed by a podium or any other obstacle, the seats were arranged like a theater, making it easier to connect with the audience. (Conference organizers, please take note.)

It was lucky that I arrived early to test the video and audio. If you own a MacBook Pro, you may or may not know that it puts the sound card to sleep if it has been unused for a few minutes. (If you use headphones, you can hear when it sleeps and awakes.) When you're connected to a massive sound system for a theater, this behavior creates a really horrible noise. The solution I came up with was to play iTunes the entire time with the iTunes volume control turned all the way down. Hopefully this trick will save someone else a lot of trouble. :-)

As I began speaking, I noted that PHP had just turned 15 years old. Years ago, the community was energized by all of the misinformation being spread about PHP. It doesn't scale. It's insecure. It's not maintainable. When I began speaking about security, it was partly in response to some of this. I wanted to educate developers, so that we would not only take responsibility for the security of our apps, but also so that we could avoid the most common and dangerous security problems.

These days, petty insults probably continue in the comments on Digg or Hacker News, but no one takes them too seriously. Can PHP scale? Well, the biggest and most popular sites on the Web all use PHP, so I guess so. With no misinformation to energize us, it can easily seem like the PHP community has lost its luster. Not so.

In my talk, Security-Centered Design, I suggest we take a lesson from the design community, where user experience takes priority. We must evolve, or as Aral Balkan puts it:

The age of features is dead; welcome to the age of user experience.

My talk revolves loosely around security, but it's really a call to arms for my developer peers to take a step back and consider the bigger picture. We need to zoom out. Sometimes, even with a subject as technical as security, the social elements of the problems we face are just as important as the technical. If we can't empathize with users, we can't be great developers.

I want to thank everyone who took the time to say nice things about my talk. Hearing it described as the "best keynote I have ever seen" and the "highlight of the event" is really encouraging and makes it all worthwhile. I can't possibly thank you enough.

I'll leave you with a little taste of the talk where I invite everyone to participate in a change blindness experiment. I may discuss change blindness and how it applies to the Web in more detail later, but for now, see if you can spot the difference in the two photos I used in the change blindness video I created for this talk.

Thanks again to everyone who woke up early after a late night at the conference social to see me speak, and I hope to see you again sometime. :-)

Wed, 30 Jun 2010 22:12 GMT — Chris Shiflett’s Blog Chris Shiflett’s Feed

 

Photos
Videos
Help
Visit the FAQ Page