CSC/ECE 517 Spring 2015/ch1b 21 QW: Difference between revisions
(77 intermediate revisions by 2 users not shown) | |||
Line 1: | Line 1: | ||
<font size="6"><b>Omniauth</b></font><br> | <font size="6"><b>Omniauth</b></font><br> | ||
'''Omniauth''' is a Ruby authentication framework aimed to integrated with various types of authentication providers. It can be hooked up to any system, from social network to enterprise systems to simple username and password authentication | [[File:Omniauth.jpg|frame|Source: http://intridea.github.io/omniauth/|right]] | ||
'''Omniauth''' is a Ruby authentication framework aimed to integrated with various types of authentication providers. It can be hooked up to any system, from social network to enterprise systems to simple username and password authentication <ref>https://github.com/intridea/omniauth/wiki</ref>. OmniAuth is designed to be a black box to which you can send users' requests in order to get authentication information back from the providers. For example, you can use OmniAuth Facebook strategies and send user's email and password to Facebook service, and then get information back to authenticate that user in your application. OmniAuth has the advantages of super simplicity and security. <br> | |||
The topic writeup for this page can be found [https://docs.google.com/a/ncsu.edu/document/d/1Ay5OOUkcLMC-FH61fAm3cNvB3Uyk2hJ09vHnRgqwL-k/edit here]. | The topic writeup for this page can be found [https://docs.google.com/a/ncsu.edu/document/d/1Ay5OOUkcLMC-FH61fAm3cNvB3Uyk2hJ09vHnRgqwL-k/edit here]. | ||
== Background == | == Background == | ||
=== Why Omniauth === | |||
With web application booming, most users | With web application booming, most users log into hundreds of services every day and won't expect to create a unique login and password for each service. So [http://www.intridea.com/ intridea] releases a standard library to provide multi-provider authentication for web applications in 2010. So far, thousands of users take advantage of the simple, powerful and secure authentication with OmniAuth in their web applications. From social networking sites like Facebook, Twitter, LinkedIn, to file- or media-sharing sites like Youtube, Github, to search engine sites like Google and Bing, to online e-commerce sites like Amazon and beyond, developers are relying on OmniAuth to handle user authentication in their systems. [https://github.com/intridea/omniauth/wiki/Sites-Using-OmniAuth Here] intridea lists some community-curated sites that are using OmniAuth to streamline authentication. | ||
Omniauth has following advantages: | |||
* Simple | |||
* Powerful | |||
* Flexible | |||
* Secure | |||
In order to use Omniauth for authentication, developers can create and leverage one or more [https://github.com/intridea/omniauth/wiki/List-of-Strategies strategies] released individually as RubyGems from different providers for OmniAuth. Each strategy is a Rack Middleware. | |||
=== Rack Middleware === | === Rack Middleware === | ||
Rack provides a standard interface for developing web applications supporting Ruby and Ruby framework. And Rack middleware is a way to filter a request and response coming into your application<ref>http://railscasts.com/episodes/151-rack-middleware</ref>. Rack has quite simple architecture: | Rack provides a standard interface for developing web applications supporting Ruby and Ruby framework. And Rack middleware is a way to filter a request and response coming into your application<ref>http://railscasts.com/episodes/151-rack-middleware</ref>. Rack has quite simple architecture: | ||
* An object that responds to the <code>call</code> method | |||
* Taking the environment hash as a parameter | |||
* Returning an Array with three elements: status code, environment hash and response body | |||
We can install Rack with following command: | We can install Rack with following command: | ||
<pre>$ gem install rack</pre> | <pre>$ gem install rack</pre> | ||
Then we're going to create a Rack configuration file with extension .ru in your Rails application's root directory. That | Then we're going to create a Rack configuration file with extension .ru in your Rails application's root directory. That tells <code>Rack::Builder</code> what middleware does it use and in which order. Or to say how to combine various internal and external middlewares to form a complete Rails Rack application<ref name = "Rack Middleware">http://guides.rubyonrails.org/rails_on_rack.html</ref>. <code>Rack::Builder</code> is Rails equivalent of <code>ActionDispatch::MiddlewareStack</code>. | ||
<pre> | <pre> | ||
#config.ru | #Rails.root/config.ru | ||
require 'rack' | require 'rack' | ||
</pre> | </pre> | ||
To use <code>rackup</code> to | To use <code>rackup</code> to start up your created app, you can put the following code inside config.ru<ref name = "Rack Middleware">http://guides.rubyonrails.org/rails_on_rack.html</ref>. And then run <code>rackup</code> command: | ||
<pre>require ::File.expand_path('../config/environment', __FILE__) | <pre>require ::File.expand_path('../config/environment', __FILE__) | ||
Line 30: | Line 37: | ||
</pre> | </pre> | ||
<pre>$ rackup config.ru</pre> | <pre>$ rackup config.ru</pre> | ||
Creating a Middleware filter is just creating a Ruby class. Here is an simplest example: | |||
<pre># ResponseTimer.rb | |||
class ResponseTimer | |||
def initialize(app) | |||
@app = app | |||
end | |||
def call(env) | |||
@app.call(env) | |||
end | |||
end | |||
</pre> | |||
By binding HTTP requests and responses together in the simplest way, it unifies the API for web servers, web frameworks, and software into a single method <code>call</code>. | |||
Rails also provides some simple configuration interface <code>config.middleware</code> for adding, modifying and removing middlewares in the middleware stack via application.rb or the environment configuration file <code>environments/<environment>.rb. </code>You can check out these methods by view Configuring Middleware Stack part of <ref name = "Rack Middleware">http://guides.rubyonrails.org/rails_on_rack.html</ref> | |||
=== | ===Supported Ruby Versions=== | ||
OmniAuth is tested under 1.8.7, 1.9.3, 2.0.0, 2.1.0, JRuby, and Rubinius. | |||
== Getting | == Getting Started == | ||
Because each OmniAuth strategy is a Rack Middleware, this means it can be used the same way as other Rack middleware. Here we introduce some simple steps in order to illustrate how to use Twitter strategy for OmniAuth<ref>https://github.com/intridea/omniauth</ref>. | |||
=== Installing === | === Installing === | ||
First start by adding this gem | First start by adding this gem into your Gemfile: | ||
<pre>gem 'omniauth-twitter'</pre> | <pre>gem 'omniauth-twitter'</pre> | ||
If you need to use the latest HEAD version, you can do | If you need to use the latest HEAD version, you can do it with: | ||
<pre>gem 'omniauth-twitter', :github => 'arunagw/omniauth-twitter'</pre> | <pre>gem 'omniauth-twitter', :github => 'arunagw/omniauth-twitter'</pre> | ||
Line 51: | Line 74: | ||
end | end | ||
</pre> | </pre> | ||
You can create your twitter application [https://apps.twitter.com/ here], after that, you can obtain <code>TWITTER_KEY</code> and <code>TWITTER_SECRET</code> as shown below: | |||
[[File: twitter.png|center]] | |||
=== Integrating OmniAuth into Rails Application === | === Integrating OmniAuth into Rails Application === | ||
To use OmniAuth, you need to redirect users to <code>/auth/:provider</code> , where <code>:provider</code> is the name of the strategy (for example, <code>facebook</code> or <code>twitter</code> ). From there, OmniAuth will take over and take the user through the necessary steps to authenticate them with the chosen strategy. | |||
Once the user has authenticated, OmniAuth simply | Once the user has authenticated, OmniAuth simply set a special hash called Authentication Hash on Rack environment of a request to <code>/auth/:provider/callback</code>. This hash includes information about the user that OmniAuth collects from the utilized strategy. You should set up an endpoint in your application that matches to the callback URL and then performs whatever steps are necessary for your application. | ||
For example, in a Rails app you can add a line in <code>routes.rb</code> file like this: | For example, in a Rails app you can add a line in <code>routes.rb</code> file like this: | ||
<pre>get '/auth/:provider/callback', to: 'sessions#create'</pre> | <pre>get '/auth/:provider/callback', to: 'sessions#create'</pre> | ||
Then you can add code in <code>SessionsController</code> with something like this: | |||
<pre>class SessionsController < ApplicationController | <pre>class SessionsController < ApplicationController | ||
def create | def create | ||
Line 86: | Line 98: | ||
end | end | ||
end</pre> | end</pre> | ||
The <code>omniauth.auth</code> key in the environment hash gives the Authentication Hash which will contain information about the just authenticated user | The <code>omniauth.auth</code> key in the environment hash gives you the Authentication Hash which will contain information about the just authenticated user. The information includes a unique id, the strategy used for authentication, and personal details such as name and email address. | ||
Note that OmniAuth does not perform any actions beyond setting some environment information on the callback request. It | Note that OmniAuth does not perform any actions beyond setting some environment information on the callback request. It depends on how you want to implement the particulars of your application's authentication flow. | ||
=== Logging === | === Logging === | ||
Line 98: | Line 110: | ||
=== OmniAuth Facebook === | === OmniAuth Facebook === | ||
==== Installing ==== | ==== Installing ==== | ||
To use Facebook OmniAuth Strateges<ref>https://github.com/mkdynamic/omniauth-facebook</ref>, first, add this gem into your Gemfile, and then run <code>bundle install</code>: | To use Facebook OmniAuth Strateges<ref name = "omniauth-facebook">https://github.com/mkdynamic/omniauth-facebook</ref>, first, add this gem into your Gemfile, and then run <code>bundle install</code>: | ||
<pre>gem 'omniauth-facebook'</pre> | <pre>gem 'omniauth-facebook'</pre> | ||
==== Usage==== | ==== Usage==== | ||
Adding the middleware to a Rails app in <code>config/initializers/omniauth.rb</code>: | Adding the middleware to a Rails app in <code>config/initializers/omniauth.rb</code>: | ||
Line 106: | Line 119: | ||
end</pre> | end</pre> | ||
==== Configuring ==== | ==== Configuring ==== | ||
You can configure several options, which you pass in to the <code>provider</code> method via a <code>Hash</code><ref name = "omniauth-facebook">https://github.com/mkdynamic/omniauth-facebook</ref>: | |||
{| class="wikitable" style="font-size: 100%; text-align: left; width: auto;" | {| class="wikitable" style="font-size: 100%; text-align: left; width: auto;" | ||
Line 174: | Line 188: | ||
provider :github, ENV['GITHUB_KEY'], ENV['GITHUB_SECRET'], scope: "user,repo,gist" | provider :github, ENV['GITHUB_KEY'], ENV['GITHUB_SECRET'], scope: "user,repo,gist" | ||
end</pre> | end</pre> | ||
More info is shown below: | More scope info is shown below<ref>https://developer.github.com/v3/oauth/#scopes</ref>: | ||
{| class="wikitable" style="font-size: 100%; text-align: left; width: auto;" | {| class="wikitable" style="font-size: 100%; text-align: left; width: auto;" | ||
Line 266: | Line 280: | ||
|} | |} | ||
=== More Examples === | |||
* [https://github.com/arunagw/omniauth-foursquare OmniAuth Foursquare ] | |||
* [https://github.com/geoloqi/omniauth-geoloqi OmniAuth Geoloqi] | |||
* [https://github.com/intridea/omniauth-identity OmniAuth Identity] | |||
* [https://github.com/skorks/omniauth-linkedin OmniAuth Linkedin] | |||
* [https://github.com/arunagw/omniauth-picplz OmniAuth Picplz] | |||
* [https://github.com/intridea/omniauth-openid OmniAuth Openid] | |||
If you want to learn how Omniauth works more intuitively, you can find tutorial videos you are interested in [https://www.youtube.com/results?search_query=omniauth+rails on Youtube]. | |||
== References == | == References == | ||
<references/> | <references/> |
Latest revision as of 01:55, 17 March 2015
Omniauth
Omniauth is a Ruby authentication framework aimed to integrated with various types of authentication providers. It can be hooked up to any system, from social network to enterprise systems to simple username and password authentication <ref>https://github.com/intridea/omniauth/wiki</ref>. OmniAuth is designed to be a black box to which you can send users' requests in order to get authentication information back from the providers. For example, you can use OmniAuth Facebook strategies and send user's email and password to Facebook service, and then get information back to authenticate that user in your application. OmniAuth has the advantages of super simplicity and security.
The topic writeup for this page can be found here.
Background
Why Omniauth
With web application booming, most users log into hundreds of services every day and won't expect to create a unique login and password for each service. So intridea releases a standard library to provide multi-provider authentication for web applications in 2010. So far, thousands of users take advantage of the simple, powerful and secure authentication with OmniAuth in their web applications. From social networking sites like Facebook, Twitter, LinkedIn, to file- or media-sharing sites like Youtube, Github, to search engine sites like Google and Bing, to online e-commerce sites like Amazon and beyond, developers are relying on OmniAuth to handle user authentication in their systems. Here intridea lists some community-curated sites that are using OmniAuth to streamline authentication. Omniauth has following advantages:
- Simple
- Powerful
- Flexible
- Secure
In order to use Omniauth for authentication, developers can create and leverage one or more strategies released individually as RubyGems from different providers for OmniAuth. Each strategy is a Rack Middleware.
Rack Middleware
Rack provides a standard interface for developing web applications supporting Ruby and Ruby framework. And Rack middleware is a way to filter a request and response coming into your application<ref>http://railscasts.com/episodes/151-rack-middleware</ref>. Rack has quite simple architecture:
- An object that responds to the
call
method - Taking the environment hash as a parameter
- Returning an Array with three elements: status code, environment hash and response body
We can install Rack with following command:
$ gem install rack
Then we're going to create a Rack configuration file with extension .ru in your Rails application's root directory. That tells Rack::Builder
what middleware does it use and in which order. Or to say how to combine various internal and external middlewares to form a complete Rails Rack application<ref name = "Rack Middleware">http://guides.rubyonrails.org/rails_on_rack.html</ref>. Rack::Builder
is Rails equivalent of ActionDispatch::MiddlewareStack
.
#Rails.root/config.ru require 'rack'
To use rackup
to start up your created app, you can put the following code inside config.ru<ref name = "Rack Middleware">http://guides.rubyonrails.org/rails_on_rack.html</ref>. And then run rackup
command:
require ::File.expand_path('../config/environment', __FILE__) use Rails::Rack::Debugger use Rack::ContentLength run Rails.application
$ rackup config.ru
Creating a Middleware filter is just creating a Ruby class. Here is an simplest example:
# ResponseTimer.rb class ResponseTimer def initialize(app) @app = app end def call(env) @app.call(env) end end
By binding HTTP requests and responses together in the simplest way, it unifies the API for web servers, web frameworks, and software into a single method call
.
Rails also provides some simple configuration interface config.middleware
for adding, modifying and removing middlewares in the middleware stack via application.rb or the environment configuration file environments/<environment>.rb.
You can check out these methods by view Configuring Middleware Stack part of <ref name = "Rack Middleware">http://guides.rubyonrails.org/rails_on_rack.html</ref>
Supported Ruby Versions
OmniAuth is tested under 1.8.7, 1.9.3, 2.0.0, 2.1.0, JRuby, and Rubinius.
Getting Started
Because each OmniAuth strategy is a Rack Middleware, this means it can be used the same way as other Rack middleware. Here we introduce some simple steps in order to illustrate how to use Twitter strategy for OmniAuth<ref>https://github.com/intridea/omniauth</ref>.
Installing
First start by adding this gem into your Gemfile:
gem 'omniauth-twitter'
If you need to use the latest HEAD version, you can do it with:
gem 'omniauth-twitter', :github => 'arunagw/omniauth-twitter'
Usage
Because OmniAuth is built for multi-provider authentication, you need to build multiple strategies. For this, the Rack middleware OmniAuth::Builder
class gives an easy way to build up your list of OmniAuth strategies for use in your application.
Below is an example that you can put into a Rails initializer at config/initializers/omniauth.rb
or add it to your middleware:
Rails.application.config.middleware.use OmniAuth::Builder do provider :developer unless Rails.env.production? provider :twitter, ENV['TWITTER_KEY'], ENV['TWITTER_SECRET'] end
You can create your twitter application here, after that, you can obtain TWITTER_KEY
and TWITTER_SECRET
as shown below:
Integrating OmniAuth into Rails Application
To use OmniAuth, you need to redirect users to /auth/:provider
, where :provider
is the name of the strategy (for example, facebook
or twitter
). From there, OmniAuth will take over and take the user through the necessary steps to authenticate them with the chosen strategy.
Once the user has authenticated, OmniAuth simply set a special hash called Authentication Hash on Rack environment of a request to /auth/:provider/callback
. This hash includes information about the user that OmniAuth collects from the utilized strategy. You should set up an endpoint in your application that matches to the callback URL and then performs whatever steps are necessary for your application.
For example, in a Rails app you can add a line in routes.rb
file like this:
get '/auth/:provider/callback', to: 'sessions#create'
Then you can add code in SessionsController
with something like this:
class SessionsController < ApplicationController def create @user = User.find_or_create_from_auth_hash(auth_hash) self.current_user = @user redirect_to '/' end protected def auth_hash request.env['omniauth.auth'] end end
The omniauth.auth
key in the environment hash gives you the Authentication Hash which will contain information about the just authenticated user. The information includes a unique id, the strategy used for authentication, and personal details such as name and email address.
Note that OmniAuth does not perform any actions beyond setting some environment information on the callback request. It depends on how you want to implement the particulars of your application's authentication flow.
Logging
OmniAuth supports a configurable logger. By default, OmniAuth will log to STDOUT
but you can configure this using OmniAuth.config.logger
:
# Rails application example OmniAuth.config.logger = Rails.logger
Other Examples
OmniAuth Facebook
Installing
To use Facebook OmniAuth Strateges<ref name = "omniauth-facebook">https://github.com/mkdynamic/omniauth-facebook</ref>, first, add this gem into your Gemfile, and then run bundle install
:
gem 'omniauth-facebook'
Usage
Adding the middleware to a Rails app in config/initializers/omniauth.rb
:
Rails.application.config.middleware.use OmniAuth::Builder do provider :facebook, ENV['FACEBOOK_KEY'], ENV['FACEBOOK_SECRET'] end
Configuring
You can configure several options, which you pass in to the provider
method via a Hash
<ref name = "omniauth-facebook">https://github.com/mkdynamic/omniauth-facebook</ref>:
Option name | Default | Explanation |
---|---|---|
scope
|
email
|
A comma-separated list of permissions you want to request from the user. See the Facebook docs for a full list of available permissions |
display
|
page
|
The display context to show the authentication page. Options are: page , popup and touch . Read the Facebook docs for more details
|
image_size
|
square
|
Set the size for the returned image url in the auth hash. Valid options include square (50x50), small (50 pixels wide, variable height), normal (100 pixels wide, variable height), or large (about 200 pixels wide, variable height). Additionally, you can request a picture of a specific size by setting this option to a hash with :width and :height as keys. This will return an available profile picture closest to the requested size and requested aspect ratio. If only :width or :height is specified, we will return a picture whose width or height is closest to the requested size, respectively.
|
info_fields
|
Specify exactly which fields should be returned when getting the user's info. Value should be a comma-separated string as per <ref>https://developers.facebook.com/docs/graph-api/reference/user/</ref> | |
locale
|
Specify locale which should be used when getting the user's info. Value should be locale string as per <ref>https://developers.facebook.com/docs/reference/api/locale/</ref> | |
auth_type
|
Optionally specifies the requested authentication features as a comma-separated list <ref>https://developers.facebook.com/docs/facebook-login/reauthentication/</ref>. Valid values are https (checks for the presence of the secure cookie and asks for re-authentication if it is not present), and reauthenticate (asks the user to re-authenticate unconditionally). Default is nil .
| |
secure_image_url
|
false
|
Set to true to use https for the avatar image url returned in the auth hash
|
callback_url /
|
Specify a custom callback URL used during the server-side flow. Note this must be allowed by your app configuration on Facebook |
For example, to request email
, user_birthday
and read_stream
permissions:
Rails.application.config.middleware.use OmniAuth::Builder do provider :facebook, ENV['FACEBOOK_KEY'], ENV['FACEBOOK_SECRET'], :scope => 'email,user_birthday,read_stream' end
OmniAuth GitHub
Install
To use GitHub OmniAuth Strateges<ref>https://github.com/intridea/omniauth-github</ref>, first, add this gem into your Gemfile, and then run bundle install
:
gem 'omniauth-github'
Usage
Adding the middleware to a Rails app in config/initializers/omniauth.rb
:
Rails.application.config.middleware.use OmniAuth::Builder do provider :github, ENV['GITHUB_KEY'], ENV['GITHUB_SECRET'] end
Scopes
GitHub API v3 lets you set scopes to provide granular access to different types of data:
use OmniAuth::Builder do provider :github, ENV['GITHUB_KEY'], ENV['GITHUB_SECRET'], scope: "user,repo,gist" end
More scope info is shown below<ref>https://developer.github.com/v3/oauth/#scopes</ref>:
Name | Description |
---|---|
(no scope)
|
Grants read-only access to public information (includes public user profile info, public repository info, and gists) |
user
|
Grants read/write access to profile info only. Note that this scope includes user:email and user:follow
|
user:email
|
Grants read access to a user’s email addresses |
user:follow
|
Grants access to follow or unfollow other users |
public_repo
|
Grants read/write access to code, commit statuses, and deployment statuses for public repositories and organizations |
repo
|
Grants read/write access to code, commit statuses, and deployment statuses for public and private repositories and organizations |
repo_deployment
|
Grants access to deployment statuses for public and private repositories. This scope is only necessary to grant other users or services access to deployment statuses, without granting access to the code |
repo:status
|
Grants read/write access to public and private repository commit statuses. This scope is only necessary to grant other users or services access to private repository commit statuses without granting access to the code |
delete_repo
|
Grants access to delete adminable repositories |
notifications
|
Grants read access to a user’s notifications. repo also provides this access |
gist
|
Grants write access to gists |
read:repo_hook
|
Grants read and ping access to hooks in public or private repositories |
write:repo_hook
|
Grants read, write, and ping access to hooks in public or private repositories |
admin:repo_hook
|
Grants read, write, ping, and delete access to hooks in public or private repositories |
admin:org_hook
|
Grants read, write, ping, and delete access to organization hooks. Note: OAuth tokens will only be able to perform these actions on organization hooks which were created by the OAuth application. Personal access tokens will only be able to perform these actions on organization hooks created by a user |
read:org
|
Read-only access to organization, teams, and membership |
write:org
|
Publicize and unpublicize organization membership |
admin:org
|
Fully manage organization, teams, and memberships |
read:public_key
|
List and view details for public keys |
write:public_key
|
Create, list, and view details for public keys |
admin:public_key
|
Fully manage public keys |
More Examples
- OmniAuth Foursquare
- OmniAuth Geoloqi
- OmniAuth Identity
- OmniAuth Linkedin
- OmniAuth Picplz
- OmniAuth Openid
If you want to learn how Omniauth works more intuitively, you can find tutorial videos you are interested in on Youtube.
References
<references/>