LoginSignup
1
1

More than 5 years have passed since last update.

[Ruby on Rails] Devise + Omniauth Authentication

Last updated at Posted at 2017-06-13

Sample Application

Gemfile
gem 'devise'
gem 'omniauth'
gem 'omniauth-facebook'
gem 'omniauth-twitter'
gem 'paperclip'
gem 'fog'

rails g devise:install
rails g devise User
rails g devise:controllers users
rails g migration AddAttributesToUsers name uid provider token
rails g paperclip user image

config/routes.rb
devise_for :users, controllers: {
  omniauth_callbacks: 'users/omniauth_callbacks',
  registrations: 'users/registrations'
}
config/initializers/devise.rb
config.omniauth :facebook, ENV['FACEBOOK_API_KEY'], ENV['FACEBOOK_API_SECRET'],
  secure_image_url: true
config.omniauth :twitter, ENV['TWITTER_API_KEY'], ENV['TWITTER_API_SECRET']
config/environments/production.rb
  config.paperclip_defaults = {
    use_timestamp: false,
    url: '/:attachment/:class/:id/:style.:extension',
    storage: :fog,
    fog_directory: ENV['FOG_DIRECTORY'],
    fog_credentials: {
      provider: :aws,
      region: 'ap-northeast-1',
      aws_access_key_id: ENV['AWS_API_KEY'],
      aws_secret_access_key: ENV['AWS_API_SECRET']
    }
  }
app/models/user.rb
  devise :database_authenticatable, :registerable, :omniauthable,
         :recoverable, :rememberable, :trackable, :validatable

  has_attached_file :image, styles: { thumb: '50x50#' }
  validates_attachment_content_type :image, content_type: /\Aimage\/.*\z/

  def self.find_for_oauth(auth)
    user = User.where(uid: auth.uid, provider: auth.provider).first
    unless user
      user = User.create(
        uid: auth.uid,
        provider: auth.provider,
        token: auth.credentials.token,
        name: auth.info.name,
        email: User.get_email(auth),
        password: Devise.friendly_token[0, 20]
      )
    end
    if auth.info.image
      user.update_attribute(:image, auth.info.image)
    end
    user
  end

  private

  def self.get_email(auth)
    auth.info.email || "#{auth.provider}-#{auth.uid}@example.com"
  end
app/controllers/users/registrations_controller.rb
protected
  # If you have extra params to permit, append them to the sanitizer.
  def configure_sign_up_params
    devise_parameter_sanitizer.permit(:sign_up, keys: [:name, :image])
  end

  # If you have extra params to permit, append them to the sanitizer.
  def configure_account_update_params
    devise_parameter_sanitizer.permit(:account_update, keys: [:name, :image])
  end

  # Can update without current password
  def update_resource(resource, params)
    # Require current password if user is trying to change password
    return super if params['password']&.present?

    # Allows user to update registration information without password
    resource.update_without_password(params.except('current_password'))
  end
app/controllers/users/omniauth_callbacks_controller.rb
  def facebook
    callback_from :facebook
  end

  def twitter
    callback_from :twitter
  end

  private

  def callback_from(provider)
    provider = provider.to_s
    @user = User.find_for_oauth(request.env['omniauth.auth'])
    if @user.persisted?
      flash[:success] = I18n.t('devise.omniauth_callbacks.success', kind: provider.capitalize)
      sign_in_and_redirect @user, event: :authentication
    else
      if provider == 'twitter'
        session["devise.#{provider}_data"] = request.env['omniauth.auth'].except('extra')
      else
        session["devise.#{provider}_data"] = request.env['omniauth.auth']
      end
      redirect_to new_user_registration_url
    end
  end
app/views/layouts/application.erb.slim
          ul.nav.navbar-nav.navbar-right
            - if user_signed_in?
              li = image_tag current_user.image(:thumb)
              li.navbar-text = current_user.name
              li = link_to 'Sign out', destroy_user_session_path, method: :delete
            - else
              li = link_to 'Sign in', new_user_session_path
              li = link_to 'Sign up', new_user_registration_path
              li = link_to 'Sign up with Facebook', user_facebook_omniauth_authorize_path
              li = link_to 'Sign up with Twitter', user_twitter_omniauth_authorize_path

スクリーンショット 2017-06-13 18.23.21.png

Paperclip::AdapterRegistry::NoHandlerError というエラーが発生した場合

config/initializers/paperclip.rb
Paperclip::DataUriAdapter.register
1
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
1