Registrar: Standardized Multi-Provider Registration
Gem | Source | Documentation
Introduction
Registrar standardizes the authentication process through Rack Middleware and works well with common authentication mechanisms like OmniAuth.
Description
You can think of Registrar as a thin wrapper around your sign up / sign in process.
Registrar already has build in support for the OmniAuth Auth Hash Schema.
If you want to use a different authentication mechanism feel free to implement your own AuthBuilder.
Getting Started
Let us start with a short example.
I'm using a fork (see here why i use a fork) of the omniauth-facebook-access-token OmniAuth strategy to authenticate my user.
Add registrar
and the authenticaton mechanism you want to use to your Gemfile
gem 'registrar'
gem 'omniauth-facebook-access-token' # we are just using one OmniAuth strategy here
Add the authentication mechanism of your choice
require 'omniauth-facebook-access-token'
app = Rack::Builder.app do
# Store authenticated user in env['omniauth.auth']
use OmniAuth::Builder do
provider omniauth-facebook-access-token
end
run lambda { |env| [200, {'Content-Type' => 'text/plain'}, ['OK']] }
end
run app
Add a appropriate AuthBuilder to your Middleware Stack to transform the previous authentication result into registrar schema.
require 'registrar'
require 'omniauth-facebook-access-token'
app = Rack::Builder.app do
# Store authenticated user in env['omniauth.auth']
use OmniAuth::Builder do
provider omniauth-facebook-access-token
end
# Transform the OmniAuth Schema env['omniauth.auth'] into the Registrar Schema env['registrar.auth']
use Registrar::AuthBuilder::OmniAuth
run lambda { |env| [200, {'Content-Type' => 'text/plain'}, ['OK']] }
end
run app
Go to the Facebook Graph API Explorer, generate an access token and copy it to your clipboard.
Start the application, visit localhost:port/auth/facebook_access_token and paste the access token from your clipboard. Click the submit button.
env['omniauth.auth']
returns the schema OmniAuth builds for you
!ruby/hash:OmniAuth::AuthHash
provider: facebook
uid: '100000100277322'
info: !ruby/hash:OmniAuth::AuthHash::InfoHash
email: [email protected]
name: Jan Ow
first_name: Jan
last_name: Ow
image: http://graph.facebook.com/100000100277322/picture
urls: !ruby/hash:OmniAuth::AuthHash
Facebook: http://www.facebook.com/100000100277322
location: Bochum, Germany
verified: true
credentials: !ruby/hash:OmniAuth::AuthHash
token: CAACEdEose0cBABZBEayxJNmeCRdvrwT6RbiEbtYUyAZCY24E5xxCoPQJ0oCVR8XFsUEtTpnMjwrRMwvjliQe2xDRM2c76ONriaNQaMwuAKH1YjQki9lK8evIkN18TqPopB1blbeRuOIkes2l4JQ3Ga7HL9vHXHqhAjcbuZCHKhtOJMulZAN1wfWMlOxF7bBZCW0TdzJz654CW7ErAsIPj
expires: false
extra: !ruby/hash:OmniAuth::AuthHash
raw_info: !ruby/hash:OmniAuth::AuthHash
id: '100000100277322'
email: [email protected]
first_name: Jan
gender: male
last_name: Ow
link: http://www.facebook.com/100000100277322
location: !ruby/hash:OmniAuth::AuthHash
id: '106544749381682'
name: Bochum, Germany
locale: en_US
name: Jan Ow
timezone: 1
updated_time: '2015-01-10T11:52:30+0000'
verified: true
env['registrar.auth']
returns the schema which registrar builds (in this case Registrar::AuthBuilder::OmniAuth)
provider:
name: facebook
uid: '100000100277322'
access_token: CAACEdEose0cBABZBEayxJNmeCRdvrwT6RbiEbtYUyAZCY24E5xxCoPQJ0oCVR8XFsUEtTpnMjwrRMwvjliQe2xDRM2c76ONriaNQaMwuAKH1YjQki9lK8evIkN18TqPopB1blbeRuOIkes2l4JQ3Ga7HL9vHXHqhAjcbuZCHKhtOJMulZAN1wfWMlOxF7bBZCW0TdzJz654CW7ErAsIPj
profile:
name: Jan Ow
email: [email protected]
location: Bochum, Germany
image: http://graph.facebook.com/100000100277322/picture
trace:
ip: 127.0.0.1
user_agent: Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko)
Chrome/40.0.2214.91 Safari/537.36
timestamp: '1427800292'
Currently, the AuthBuilder just transforms the Hash into a different structure.
To do something with the authenticated user (e.g. sign up or sign in), use the profile builder.
Open up you Middewarestack again.
require 'registrar'
require 'omniauth-facebook-access-token'
app = Rack::Builder.app do
# Store authenticated user in env['omniauth.auth']
use OmniAuth::Builder do
provider omniauth-facebook-access-token
end
# Transform the OmniAuth Schema env['omniauth.auth'] into the Registrar Schema env['registrar.auth']
use Registrar::AuthBuilder::OmniAuth
# Handle Registrar Schema env['registrar.auth'] and store processed result into env['registrar.profile']
use Registrar::ProfileBuilder, Proc.new {|schema| #find_or_create_profile_in_persistence }
run lambda { |env| [200, {'Content-Type' => 'text/plain'}, ['OK']] }
end
run app
In this case I passed the Registrar Schema to an application related service called ProfileRegister which returned me a application specific Profile.
This profile is stored in env['registrar.profile']
!ruby/object:ProfileRegister::Services::ProfileBoundary::Profile
o:
t:
:profile_uid: '1'
:provider: facebook
:access_token: a39147c2f57f3797f58a
:external_uid: '100000100277322'
:display_name: Jan Ow
:country_code:
:avatar: http://graph.facebook.com/100000100277322/picture
:email: [email protected]
:terms_accepted: false
:registration_platform:
:gender:
:language:
:birthday:
:fresh: true
:last_login: &1 !ruby/object:ProfileRegister::Services::ProfileBoundary::LastLogin
o:
t:
:time: 2015-03-31 11:11:32.000000000 Z
:address: 127.0.0.1
:user_agent: Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like
Gecko) Chrome/40.0.2214.91 Safari/537.36
If your application supports the concept of a session your could store env['registrar.profile'] in your session to log the user in.
if env['registrar.profile']
@session['current_profile'] = env['registrar.profile']
end
If you decide to do this you could also add some helper methods.
def current_profile
@session['current_profile']
end
def logged_in?
!!current_profile
end
def logged_out?
!logged_in?
end
If you are using Rails
you should probably check out registrar-rails which gives you a small interface to configure your middleware as well as some helper methods as suggested above.
Contributing
- Check out the Wiki
- Fork it ( https://github.com/JanOwiesniak/registrar/fork )
- Create your feature branch (
git checkout -b my-new-feature
) - Commit your changes (
git commit -am 'Add some feature'
) - Push to the branch (
git push origin my-new-feature
) - Create a new Pull Request