Screencast: OmniAuth

OmniAuth ist ein Ruby-Authetifierungs-Framework welches eine standardisierte Schnittstelle zu verschiedenen Authentifizierungs-Providern bietet (z.B. Facebook, OpenID). Mit dem aktuellen OmniAuth-Release 1.0 ist nun auch möglich klassisch über Benutzernamen und Passwort die Authentifizierung durchzuführen, wenn kein externer Anbieter gewünscht oder vorhanden ist. In diesem Screencast zeigt Ryan wie es installiert und verwendet werden kann.

 

Resourcen:

bash

[bash]
rails g model identity name:string email:string password_digest:string
rake db:migrate
rails g controller identities
[/bash]

Gemfile

[ruby]
gem ‚omniauth-identity‘
[/ruby]

config/initializers/omniauth.rb

[ruby]
Rails.application.config.middleware.use OmniAuth::Builder do
# …
provider :identity, on_failed_registration: lambda { |env|
IdentitiesController.action(:new).call(env)
}
end
[/ruby]

models/identity.rb

[ruby]
class Identity < OmniAuth::Identity::Models::ActiveRecord
validates_presence_of :name
validates_uniqueness_of :email
validates_format_of :email, :with => /^[-a-z0-9_+.]+@([-a-z0-9]+.)+[a-z0-9]{2,4}$/i
end
[/ruby]

sessions/new.html.erb

[html]
<p>
<strong>Don’t use these services?</strong>
<%= link_to "Create an account", new_identity_path %> or login below.
</p>

<%= form_tag "/auth/identity/callback" do %>
<div class="field">
<%= label_tag :auth_key, "Email" %><br>
<%= text_field_tag :auth_key %>
</div>
<div class="field">
<%= label_tag :password %><br>
<%= password_field_tag :password %>
</div>
<div class="actions"><%= submit_tag "Login" %></div>
<% end %>
[/html]

routes.rb

[ruby]
resources :identities
[/ruby]

identities_controller.rb

[ruby]
def new
@identity = env[‚omniauth.identity‘]
end
[/ruby]

identities/new.html.erb

[html]
<%= form_tag "/auth/identity/register" do %>
<% if @identity && @identity.errors.any? %>
<div class="error_messages">
<h2><%= pluralize(@identity.errors.count, "error") %> prohibited this account from being saved:</h2>
<ul>
<% @identity.errors.full_messages.each do |msg| %>
<li><%= msg %></li>
<% end %>
</ul>
</div>
<% end %>
<div class="field">
<%= label_tag :name %><br>
<%= text_field_tag :name, @identity.try(:name) %>
</div>
<div class="field">
<%= label_tag :email %><br>
<%= text_field_tag :email, @identity.try(:email) %>
</div>
<div class="field">
<%= label_tag :password %><br>
<%= password_field_tag :password %>
</div>
<div class="field">
<%= label_tag :password_confirmation %><br>
<%= password_field_tag :password_confirmation %>
</div>
<div class="actions"><%= submit_tag "Register" %></div>
<% end %>
[/html]

Screencast: Authentifizierung über OmniAuth

OmniAuth ist ein flixibles Authentifizierungs-System, welches auf Rack aufsetzt. In dieser Woche zeigt Ryan wie einfach man mit OmniAuth in Rails einsetzen kann.

 

Download:

Download(12 MB, 9:06)
Alternativer Download für iPod & Apple TV(12 MB, 9:06)

 

Resourcen:

 

Quellcode:

[bash]
rails g controller sessions
rails g model user provider:string uid:string name:string
rake db:migrate
[/bash]

[ruby]
# Gemfile
gem ‚omniauth‘

# config/initializers/omniauth.rb
Rails.application.config.middleware.use OmniAuth::Builder do
provider :twitter, ‚CONSUMER_KEY‘, ‚CONSUMER_SECRET‘
end

# routes.rb
match "/auth/:provider/callback" => "sessions#create"
match "/signout" => "sessions#destroy", :as => :signout

# sessions_controller.rb
def create
auth = request.env["omniauth.auth"]
user = User.find_by_provider_and_uid(auth["provider"], auth["uid"]) || User.create_with_omniauth(auth)
session[:user_id] = user.id
redirect_to root_url, :notice => "Signed in!"
end

def destroy
session[:user_id] = nil
redirect_to root_url, :notice => "Signed out!"
end

# models/user.rb
def self.create_with_omniauth(auth)
create! do |user|
user.provider = auth["provider"]
user.uid = auth["uid"]
user.name = auth["user_info"]["name"]
end
end

# application_controller.rb
helper_method :current_user

private

def current_user
@current_user ||= User.find(session[:user_id]) if session[:user_id]
end
[/ruby]

[html]
<% if current_user %>
Welcome <%= current_user.name %>!
<%= link_to "Sign Out", signout_path %>
<% else %>
<%= link_to "Sign in with Twitter", "/auth/twitter" %>
<% end %>
[/html]

Screencast: OmniAuth Teil 2

Im zweiten Teil der OmniAuth-Screencasts zeigt Ryan wie OmniAuth in Device integriert werden kann und wie neue Benutzer incl. Validierung angelegt werden können.

 

Download:

Download(25.6 MB, 15:59)
Alternativer Download für iPod & Apple TV(23.9 MB, 15:59)

 

Resourcen:

 

Quellcode:

[bash]
bundle update
rails g controller registrations
rails g devise:views
[/bash]

[ruby]
# Gemfile
gem ‚mongrel‘, ‚1.2.0.pre2‘

# config/initializers/omniauth.rbb
require ‚openid/store/filesystem‘
Rails.application.config.middleware.use OmniAuth::Builder do
provider :twitter, ‚CONSUMER_KEY‘, ‚CONSUMER_SECRET‘
provider :open_id, OpenID::Store::Filesystem.new(‚/tmp‘)
end

# authentications_controller.rb
def create
omniauth = request.env["omniauth.auth"]
authentication = Authentication.find_by_provider_and_uid(omniauth[‚provider‘], omniauth[‚uid‘])
if authentication
flash[:notice] = "Signed in successfully."
sign_in_and_redirect(:user, authentication.user)
elsif current_user
current_user.authentications.create!(:provider => omniauth[‚provider‘], :uid => omniauth[‚uid‘])
flash[:notice] = "Authentication successful."
redirect_to authentications_url
else
user = User.new
user.apply_omniauth(omniauth)
if user.save
flash[:notice] = "Signed in successfully."
sign_in_and_redirect(:user, user)
else
session[:omniauth] = omniauth.except(‚extra‘)
redirect_to new_user_registration_url
end
end
end

# models/user.rb
def apply_omniauth(omniauth)
self.email = omniauth[‚user_info‘][‚email‘] if email.blank?
authentications.build(:provider => omniauth[‚provider‘], :uid => omniauth[‚uid‘])
end

def password_required?
(authentications.empty? || !password.blank?) && super
end

# routes.rb
devise_for :users, :controllers => {:registrations => ‚registrations‘}

# registrations_controller.rb
class RegistrationsController < Devise::RegistrationsController
def create
super
session[:omniauth] = nil unless @user.new_record?
end

private

def build_resource(*args)
super
if session[:omniauth]
@user.apply_omniauth(session[:omniauth])
@user.valid?
end
end
end

# models/authentication.rb
def provider_name
if provider == ‚open_id‘
"OpenID"
else
provider.titleize
end
end
[/ruby]

Screencast: OmniAuth Teil 1

Die traditionelle Authentifizierung mit einem eigenem System wird immer mehr zur einer Ausnahme. Moderne Webapplikationen bieten daher die Anmeldung über bestehende Dienste wie OpenID, Twitter, Facebook und/oder OAuth an. OmniAuth ist ein Plugin das in Rails-App für diesen Zweck eingesetzt werden kann. Ryan zeigt in im ersten Teil wie es in Devise integriert werden kann.

 

Download:

Download(25.6 MB, 10:52)
Alternativer Download für iPod & Apple TV(22.3 MB, 10:52)

 

Resourcen:

 

Quellcode:

[bash]
bundle install
rails g nifty:scaffold authentication user_id:integer provider:string uid:string index create destroy
rake db:migrate
[/bash]

[ruby]
# Gemfile
gem ‚omniauth‘

# models/user.rb
has_many :authentications

# models/authentication.rb
belongs_to :user

# authentications_controller.rb
def index
@authentications = current_user.authentications if current_user
end

def create
auth = request.env["rack.auth"]
current_user.authentications.find_or_create_by_provider_and_uid(auth[‚provider‘], auth[‚uid‘])
flash[:notice] = "Authentication successful."
redirect_to authentications_url
end

def destroy
@authentication = current_user.authentications.find(params[:id])
@authentication.destroy
flash[:notice] = "Successfully destroyed authentication."
redirect_to authentications_url
end
[/ruby]

[html]
<!– authentications/index.html.erb –>
<% title "Sign In" %>

<% if @authentications %>
<% unless @authentications.empty? %>
<p><strong>You can sign in to this account using:</strong></p>
<div class="authentications">
<% for authentication in @authentications %>
<div class="authentication">
<%= image_tag "#{authentication.provider}_32.png", :size => "32×32" %>
<div class="provider"><%= authentication.provider.titleize %></div>
<div class="uid"><%= authentication.uid %></div>
<%= link_to "X", authentication, :confirm => ‚Are you sure you want to remove this authentication option?‘, :method => :delete, :class => "remove" %>
</div>
<% end %>
<div class="clear"></div>
</div>
<% end %>
<p><strong>Add another service to sign in with:</strong></p>
<% else %>
<p><strong>Sign in through one of these services:</strong></p>
<% end %>

<a href="/auth/twitter" class="auth_provider">
<%= image_tag "twitter_64.png", :size => "64×64", :alt => "Twitter" %>
Twitter
</a>
<a href="/auth/facebook" class="auth_provider">
<%= image_tag "facebook_64.png", :size => "64×64", :alt => "Facebook" %>
Facebook
</a>
<a href="/auth/google_apps" class="auth_provider">
<%= image_tag "google_64.png", :size => "64×64", :alt => "Google" %>
Google
</a>
<a href="/auth/open_id" class="auth_provider">
<%= image_tag "openid_64.png", :size => "64×64", :alt => "OpenID" %>
OpenID
</a>
<div class="clear"></div>
[/html]

[css]
// application.css
.authentications {
margin-bottom: 30px;
}

.authentication {
width: 130px;
float: left;
background-color: #EEE;
border: solid 1px #999;
padding: 5px 10px;
-moz-border-radius: 8px;
-webkit-border-radius: 8px;
position: relative;
margin-right: 10px;
}

.authentication .remove {
text-decoration: none;
position: absolute;
top: 3px;
right: 3px;
color: #333;
padding: 2px 4px;
font-size: 10px;
}

.authentication .remove:hover {
color: #CCC;
background-color: #777;
-moz-border-radius: 6px;
-webkit-border-radius: 6px;
}

.authentication img {
float: left;
margin-right: 10px;
}

.authentication .provider {
font-weight: bold;
}

.authentication .uid {
color: #666;
font-size: 11px;
}

.auth_provider img {
display: block;
}

.auth_provider {
float: left;
text-decoration: none;
margin-right: 20px;
text-align: center;
margin-bottom: 10px;
}
[/css]