-
Star
(107)
You must be signed in to star a gist -
Fork
(46)
You must be signed in to fork a gist
-
-
Save schleg/993566 to your computer and use it in GitHub Desktop.
| gem 'pg' | |
| group :development do | |
| gem 'ruby-debug' | |
| end | |
| gem 'rake', '~> 0.8.7' | |
| gem 'devise' | |
| gem 'oa-oauth', :require => 'omniauth/oauth' | |
| gem 'omniauth' | |
| gem 'haml' | |
| gem 'dynamic_form' | |
| gem 'sass' | |
| gem 'jquery-rails' | |
| gem 'cancan' | |
| gem 'uuidtools' |
| # /db/migrate/<timestamp>_devise_create_users.rb | |
| class DeviseCreateUsers < ActiveRecord::Migration | |
| def self.up | |
| create_table(:users) do |t| | |
| t.database_authenticatable :null => false | |
| t.recoverable | |
| t.rememberable | |
| t.trackable | |
| t.encryptable | |
| t.confirmable | |
| t.lockable :lock_strategy => :failed_attempts, :unlock_strategy => :both | |
| t.token_authenticatable | |
| t.timestamps | |
| end | |
| add_index :users, :email, :unique => true | |
| add_index :users, :reset_password_token, :unique => true | |
| add_index :users, :confirmation_token, :unique => true | |
| add_index :users, :unlock_token, :unique => true | |
| add_index :users, :authentication_token, :unique => true | |
| end | |
| def self.down | |
| drop_table :users | |
| end | |
| end |
| # config/environments | |
| config.action_mailer.perform_deliveries = true | |
| config.action_mailer.raise_delivery_errors = true | |
| config.action_mailer.default_url_options = { :host => 'localhost:3000' } | |
| HOST = 'localhost:3000' | |
| ADMIN_EMAIL_FROM = "" | |
| PONY_VIA_OPTIONS = { | |
| :address => 'smtp.gmail.com', | |
| :port => '587', | |
| :enable_starttls_auto => true, | |
| :user_name => '', | |
| :password => '', | |
| :authentication => :plain, | |
| :domain => "localhost.localdomain" } |
| # app/config/initializers/devise.rb | |
| Devise.setup do |config| | |
| ... | |
| config.sign_out_via = :get | |
| ... | |
| config.omniauth :facebook, "KEY", "SECRET" | |
| config.omniauth :twitter, "KEY", "SECRET" | |
| config.omniauth :linked_in, "KEY", "SECRET" | |
| ... | |
| end |
| class Users::OmniauthCallbacksController < Devise::OmniauthCallbacksController | |
| require 'uuidtools' | |
| def facebook | |
| oauthorize "Facebook" | |
| end | |
| def twitter | |
| oauthorize "Twitter" | |
| end | |
| def linked_in | |
| oauthorize "LinkedIn" | |
| end | |
| def passthru | |
| render :file => "#{Rails.root}/public/404.html", :status => 404, :layout => false | |
| end | |
| private | |
| def oauthorize(kind) | |
| @user = find_for_ouath(kind, env["omniauth.auth"], current_user) | |
| if @user | |
| flash[:notice] = I18n.t "devise.omniauth_callbacks.success", :kind => kind | |
| session["devise.#{kind.downcase}_data"] = env["omniauth.auth"] | |
| sign_in_and_redirect @user, :event => :authentication | |
| end | |
| end | |
| def find_for_ouath(provider, access_token, resource=nil) | |
| user, email, name, uid, auth_attr = nil, nil, nil, {} | |
| case provider | |
| when "Facebook" | |
| uid = access_token['uid'] | |
| email = access_token['extra']['user_hash']['email'] | |
| auth_attr = { :uid => uid, :token => access_token['credentials']['token'], :secret => nil, :name => access_token['extra']['user_hash']['name'], :link => access_token['extra']['user_hash']['link'] } | |
| when "Twitter" | |
| uid = access_token['extra']['user_hash']['id'] | |
| name = access_token['user_info']['name'] | |
| auth_attr = { :uid => uid, :token => access_token['credentials']['token'], :secret => access_token['credentials']['secret'], :name => name, :link => "http://twitter.com/#{name}" } | |
| when 'LinkedIn' | |
| uid = access_token['uid'] | |
| name = access_token['user_info']['name'] | |
| auth_attr = { :uid => uid, :token => access_token['credentials']['token'], :secret => access_token['credentials']['secret'], :name => name, :link => access_token['user_info']['public_profile_url'] } | |
| else | |
| raise 'Provider #{provider} not handled' | |
| end | |
| if resource.nil? | |
| if email | |
| user = find_for_oauth_by_email(email, resource) | |
| elsif uid && name | |
| user = find_for_oauth_by_uid(uid, resource) | |
| if user.nil? | |
| user = find_for_oauth_by_name(name, resource) | |
| end | |
| end | |
| else | |
| user = resource | |
| end | |
| auth = user.authorizations.find_by_provider(provider) | |
| if auth.nil? | |
| auth = user.authorizations.build(:provider => provider) | |
| user.authorizations << auth | |
| end | |
| auth.update_attributes auth_attr | |
| return user | |
| end | |
| def find_for_oauth_by_uid(uid, resource=nil) | |
| user = nil | |
| if auth = Authorization.find_by_uid(uid.to_s) | |
| user = auth.user | |
| end | |
| return user | |
| end | |
| def find_for_oauth_by_email(email, resource=nil) | |
| if user = User.find_by_email(email) | |
| user | |
| else | |
| user = User.new(:email => email, :password => Devise.friendly_token[0,20]) | |
| user.save | |
| end | |
| return user | |
| end | |
| def find_for_oauth_by_name(name, resource=nil) | |
| if user = User.find_by_name(name) | |
| user | |
| else | |
| user = User.new(:name => name, :password => Devise.friendly_token[0,20], :email => "#{UUIDTools::UUID.random_create}@host") | |
| user.save false | |
| end | |
| return user | |
| end | |
| end |
| class RegistrationsController < Devise::RegistrationsController | |
| def update | |
| if params[resource_name][:password].blank? | |
| params[resource_name].delete(:password) | |
| params[resource_name].delete(:password_confirmation) if params[resource_name][:password_confirmation].blank? | |
| end | |
| # Override Devise to use update_attributes instead of update_with_password. | |
| # This is the only change we make. | |
| if resource.update_attributes(params[resource_name]) | |
| set_flash_message :notice, :updated | |
| # Line below required if using Devise >= 1.2.0 | |
| sign_in resource_name, resource, :bypass => true | |
| redirect_to after_update_path_for(resource) | |
| else | |
| clean_up_passwords(resource) | |
| render_with_scope :edit | |
| end | |
| end | |
| end |
| devise_for :users, :path => "accounts", :controllers => { :omniauth_callbacks => "users/omniauth_callbacks", :registrations => "registrations" } |
| # app/models/user.rb | |
| class User < ActiveRecord::Base | |
| devise :database_authenticatable, :registerable, :recoverable, :rememberable, :trackable, :validatable, :confirmable, :omniauthable | |
| attr_accessible :email, :name, :password, :password_confirmation, :remember_me | |
| has_many :authorizations, :dependent => :destroy | |
| end |
If you try this code in rails 3.1 you need to change file omniauth_callbacks_controller.rb line 95 from
user.save false
to
user.save :validate => false
Very awesome. Quick tip - as of now you'll need to specify the omniauth gem version explicitly as the 1.0 is incompatible with devise at the moment.
gem 'omniauth', '0.3.2'
See omniauth/omniauth#496 for more info.
Also FWIW :lockable is in the migration but not on the User model.
This is for omniauth with version < 1.0. For those of you who wants to use new omniauth 1.0 with devise, follow strategies on
https://github.com/intridea/omniauth/wiki/List-of-Strategies
Line 27: session["devise.#{kind.downcase}_data"] = env["omniauth.auth"]
Line 28: sign_in_and_redirect @user, :event => :authentication
Line 27 should go after Line 28, because Devise resets the session when the user is signed in.
The migration provided here won't work on Devise 2.0+. See https://github.com/plataformatec/devise/wiki/How-To:-Upgrade-to-Devise-2.0-migration-schema-style for details on how to upgrade. I think this tut might be a little outdated from the get-go.
user.rb:5 needs also to have :omniauth_providers => [:facebook, :twitter, :gplus] and etc. in the devise line in the model.
Do you really want rememberable and database_authenticatable? do those make sense to use with omniauth?
I searched long and hard for a good multi-provider example of Devise with Omniauth (using Devise's omniauthable). Great to have finally found one.!!