WordPress Authentication Framework: Keyring

Keyring: An authentication framework for your plugins

Quite a while ago (like, in at least 2009), I started thinking about regaining control of all the content I was producing online. I was posting photos to Flickr, saving bookmarks to Delicious. I started Tweeting. I was checking in. All fun and games, and all of those services offer great tools for interacting with them (let’s face it, tools that are much better than WordPress’, because they are focussed on one thing). So I figured, why not write importers for these services and pull my content back over to my WordPress. And keep doing it periodically, so that I could keep using those tools. I want WordPress to be my “home on the web”, my digital hub, but I want to use these neat tools with their fancy apps and what-have-you.

Very quickly, I realized that if I was going to do anything useful on most web services, I’d need to be able to authenticate with them. No biggie, right? I know my username and password… Oh. Right. OAuth. Turns out that most web services use OAuth (or something similar) to authenticate, and it turns out that that’s actually a bit of a bear to implement, when all you want to do is write a simple little Twitter importer. And then again for a Foursquare importer. And a Flickr importer.

What I needed was a shared, generic authentication framework that would do all the heavy lifting for me. I would tell it I wanted a connection to specific service, and if it didn’t have one, it’d walk the user through the process of getting one. It’d give me a standardized format of authentication credentials and abstract out all the complexity of making authenticated requests against those services. Then it would make me a coffee*. What I needed, was Keyring.

And so Keyring was born. Basically it’s a bunch of code that’ll handle external authentication with a web service so you don’t have to. It’ll store tokens/passwords/whatever, can talk to all kinds of different services, and is really, really extendable. It also has hooks. Lots of them. So if you want to do something custom, you probably can. It’s intended to be a foundation for writing other plugins, and really doesn’t do much interesting on its own.

I already have importers written for Twitter, Delicious and Foursquare which are based on Keyring and so far they’re working pretty nicely. There’s a lot of work to go on this project though. For Keyring to be a truly powerful framework, I need to:

  • Drastically improve the UI, which is a hodge-podge of hideousness at the moment
  • Improve a few parts of the Core UX which are pretty clunky right now
  • Put in some more failsafes/helpers for making sure things are up and running before allowing plugins to use Keyring
  • Improve internal security
  • Tighten up Permissions/Roles restrictions all over the place
  • Handle multi-user blogs (especially around token storage)
  • Work on Multi-Site
  • Support more services (preferences? suggestions?)
  • Figure out a good way of allowing people to drop in their own Service extensions (and not overwrite them with updates)
  • Improve the handling of auth flows in other plugins, and preferably move as much of that logic as possible into Keyring Core

I’m slowly working on this, but it’s all kind of a personal project at this point, so it’s just a few hours here and there. My main goal is to get it functioning so that I can get my content back. Once that’s done, then I’ll spend more time tightening it up for other/platform use. I also have a couple of other “companion plugins” that I’m working on — auto-linking text for Twitter @mentions and #hashtags, mining posts and downloading remote media (e.g. Instagram images) and some stuff around geo for mapping things like Tweets and Foursquare checkins (all the geo-data is imported in the importers I wrote).

Next on the list is abstracting and then releasing the importers that I have. That will give people something more tangible to use as an example. After that I’ll be working on a Flickr importer, but that’s a pretty big project in and of itself.

So, what do you think? Useful? Waste of time? Massive, gaping, horrendous holes? LMK (in the comments) and we’ll see what we can do.

And you know the drill — patches welcome 😉

* Sadly, Keyring will not make you coffee. Yet.

  1. Adam Kellogg said:

    I really like the concept of this plugin. I am looking at integrating a few APIs into my wordpress site. Does this store keys by user, or just by service? I would like to integrate this so that each user on the site can register keys for each service. The main services I am looking to integrate are Github and Linkedin. I will be adding this to my development site to play with.

    • Beau Lebens said:

      Hi Adam — I haven't started doing any testing yet with multiple users, but definitely the plan is to allow multiple users to store their own tokens, per service. I'd love to add additional Service definitions for LinkedIn and Github if you get to writing them, as I'm sure you're not the only person who'd like to be able to connect to them!

      • Adam Kellogg said:

        I am having an issue activating on multi-site installation at keyring.php line 266. When I have a moment I will dig into the code and see what I can find. I am also job hunting, so I have a little time. I look forward to working with your plugin.

        • Beau Lebens said:

          Hmmm, OK. Thanks for trying it out — I haven't tried this *at all* on MS yet, so no idea what will happen/break. I will probably switch over my development to being on MS soon, now that I have a base. Will also start looking at multi-user scenarios and making sure tokens are only accessible to their owners etc etc. Probably going to be some pretty big changes coming as well, as I start really rolling it around and trying it out in some different scenarios.

  2. Phil said:

    Using your plugin to create a solution for one of our site. I'll see how it goes, by the way great looking blog, noticed the .com.au, you originally from Australia?

    • Beau Lebens said:

      Cool! Unfortunately things are still moving around a bit, so you might find that you need to make a bunch of edits to keep up with the shifting APIs etc, but it should start stabilizing pretty soon.

      I grew up in Australia, but moved out to the US about 8 years ago 😉

  3. Gotequity said:

    Hi Beau,

    I've been searching for weeks for a simple API parser, and am excited about testing your plugin on one of my subdomains. The only thing standing in the way is that everytime I try to install and activate, either through the WP admin or FTP, it always results in a "500 Internal Service Error". Checked the server logs and found this: "unexpected T_PAAMAYIM_NEKUDOTAYIM in …/plugins/keyring/service.php on line 75".

    I'm going to go through the code to see if I can hack a solution, but wanted to share with you as well in case others encounter this issue.


  4. Gotequity said:

    OK, I just got it installed. There were two issues at play… the first error (shown above) was because my server was running PHP 5.2.17. After upgrading to PHP 5.3 the "unexpected T_PAAMAYIM_NEKUDOTAYIM" was resolved.

    The second fatal error was thrown after reinstalling Keyring with PHP 5.3 activated – "Cannot redeclare class OAuthException in …/plugins/keyring/includes/oauth-php/OAuth.php on line 8". Basically the OAuth service was being called twice (probably by another plugin). As a fix, I deleted rows 4-8 in OAuth.php and reinstalled the plugin without any errors.

    Hope this is helpful for anyone else who runs into a similar issue.

    • Beau Lebens said:

      It should have told you where it was previously declared (as you said, probably another plugin). That's a good point though, I should make sure that the class is only conditionally included if it's not already available to avoid errors like that. Thanks!

      Also, the T_PAAMAYIM_NEKUDOTAYIM is a "known" issue. I might fix it, but for now PHP 5.3 is required for Keyring to work properly (as mentioned in the FAQ 😉 )

Comments are closed.