OmniAuth 1.0: Auth for All

Today I'm happy to announce that OmniAuth version 1.0.0 has been released into the wild. The result of more than a month of heavy development, the newest version of OmniAuth brings along with it a slate of new features, a whole new structure, and the tools to let OmniAuth be your only authentication library. The one thing that hasn't changed is OmniAuth's mission: to assume nothing about how your app works and what you want to do with authentication.

Breaking up the Band

OmniAuth was first written to abstract the common parts of authentication to external service providers like Twitter and Facebook. It launched as a small collection of gems that each contained many strategies (for instance, the oa-oauth gem contained Twitter and LinkedIn strategies). As OmniAuth's popularity grew five strategies became fifty-five. Releases became fewer and further between because of the overhead of managing pull requests and issues for dozens of strategies.

No more. Starting with OmniAuth 1.0, each and every OmniAuth strategy will live in its own gem. The downside of this for end users is that you will have a few more lines to declare in your Gemfiles. The upsides, however, are numerous:

  1. There is no longer a gatekeeper to releasing an OmniAuth strategy. Just build a gem, release it, and link it from the new strategy list wiki page.
  2. Individual strategies are free to make releases as often as they'd like. Users don't have to wait for a massive OmniAuth patch or minor release to pick up fixes for changing APIs or other improvements.
  3. With a lean, focused core OmniAuth itself will be able to release more frequently and adapt itself to the needs of strategy authors.

As a final note about structural gem changes, OmniAuth 1.0 marks the beginning of strict semantic versioning for the project. For end users, this doesn't mean much. For strategy authors, that means that you can safely declare your dependency on ~> 1.0.

Identity for OmniAuth

As I began using OmniAuth in my day-to-day coding, I began to crave the flexibility of OmniAuth in even traditional authentication scenarios. I wanted a way to leverage the same unassuming, simple authentication structure even when my users logged in via username and password. Today, I'm happy to announce the first official release of omniauth-identity, an OmniAuth strategy that bridges the gap between traditional auth and OmniAuth.

With omniauth-identity you can quickly and easily set up internal identity management for your app that behaves exactly like other OmniAuth strategies. The library is simple but its implications are powerful: you can now treat internal and external authentication exactly the same in your application.

OmniAuth now ships with a Developer strategy that is essentially "fake authentication" you can use as a placeholder until you determine your app's real authentication strategies. Combined with the potential of Identity, authentication no longer has to be that annoying "first thing" you have to do before you can get down to the real business of building your app. Just drop in OmniAuth, use the Developer strategy, and implement other strategies down the road when it works for the timeline of your app. This is how I'll be building all my apps from now on, and since OmniAuth is just Rack middleware even Sinatra and other non-Rails apps can use the same techniques.

For more information on how to use omniauth-identity, see the README on GitHub.

Strategy Builders: Better Docs, Better Tools

For the 1.0 release in addition to all of the new features and structure I also tried to significantly improve the documentation for the project, especially for those who are interested in building a strategy. You can see the results of those efforts on the OmniAuth wiki which is the official repository of all documentation for OmniAuth.

Along with better documentation for developers OmniAuth 1.0 also brings along a more declarative DSL for building strategies. The new strategy API gives developers clear ways to implement consistent functionality and makes everything cleaner across the board. For more information on the tools available for strategy developers, take a look at the Strategy Contribution Guide.

App Developers: Consistency, Dynamic Strategies

While many of the improvements in OmniAuth are structural and made for strategy developers, there's also some great stuff available for everyday users of OmniAuth! Here's some highlights of new features that work across all strategies:

Auth Hash. Some small tweaks have been made to the omniauth.auth hash that is returned after authentication completes. For one, you can now access keys using method accessors (e.g. env['omniauth.auth'].info.name. The user_info key has also been renamed simply to info. The schema can be considered a stable part of the public API and any breaking changes will trigger a major version release (you can rely on OmniAuth 1.9 to support the same schema as 1.0).

Options Everywhere. As of OmniAuth 1.0, strategy authors are encouraged to make all strategy configuration happen through the options hash that is passed in on initialization. You will still have strategies that have additional arguments (such as consumer keys and secrets) for convenience, but even those can be configured instead by passing in a single options hash. This means that every configurable aspect of the strategy is handled at runtime, which brings us to the next improvement.

Better Dynamic Strategies. OmniAuth 1.0 makes it easy to dynamically alter strategies for each request using the new, universally available setup phase. Simply set the :setup option to a Rack endpoint and you can modify the strategy or anything else about the environment before passing it along to OmniAuth for normal operation.

Skip Info. Some strategies will be able to determine the UID without making additional API calls. You can pass true, false, or a lambda that takes a UID and returns true or false as to whether additional info is required. This gives you the ability to make fewer API calls for cases where you already have a user in your system, for instance.

Custom Forms. If you are utilizing an OmniAuth strategy that displays the standard OmniAuth form, you can now pass in :form => (true || false || lambda) to the strategy to instead render a custom form that conforms better to your application. This replaces the previous poorly conceived method of requiring /auth/:provider to return a 404 in order for OmniAuth to trigger.

Calling All Companies

Now that each strategy for OmniAuth is its own gem, I'm putting a public call out to any and all companies with APIs, but especially companies that are already on a Ruby stack. I would like to get companies on board for maintaining their own "official" OmniAuth strategies. This gives developers using your API the simplest possible means of authenticating to your service and will only help you get more developer traction and experimentation.

I'm also happy to announce that our first "official" strategy maintainers are none other than GitHub! You can say hello to the official GitHub OmniAuth strategy and be sure that any changes to the GitHub API will be safely transitioned into the gem immediately. My hope is that going forward many more companies will join the official strategy ranks. If you're interested in maintaining an official strategy, you don't need my permission but I'd love to hear about it so shoot me a message on GitHub.

Where's That Strategy?

Because of the structural changes to OmniAuth not all existing strategies are available at launch. I fully expect that in the coming weeks the strategy count will regain lost ground and even surpass the count as of the last 0.x release, but if your favorite strategy is missing from the official list here's what you can do about it:

  1. Find the source code for your strategy in the 0-3-stable branch
  2. Clone omniauth-contrib and add the strategy there
  3. Follow the strategy adaption guide to update the strategy for 1.0
  4. Submit a pull request!

The omniauth-contrib repository is a temporary repository for strategies that have been written but aren't robust and supported enough to have their own gem yet. This repository is not going to be maintained as an actual RubyGem and the strategies contained inside are meant to eventually be adopted by developers to become their own gems.

One More Thing

One last thing that I wanted to do for 1.0 is create a kind of living example that the community could update to have a simple example of as many strategies as possible. You can now visit omniauth.org and try out a number of authentication strategies that OmniAuth has to offer. The code is all open so you can see how simple it is to add and use OmniAuth in your applications today!

Welcome to 1.0

OmniAuth 1.0 marks an important milestone for the project and I'm looking forward to a new, leaner trajectory that lets us make changes more nimbly (and keeps the outstanding issue count low to zero). While the changes for 1.0 were mostly written by me, OmniAuth has been an outstanding community effort and it couldn't have gotten to where it is today without the efforts of @sferik and countless other contributors. I hope you enjoy the new release and look forward to hearing your feedback!