Skip to content

Instantly share code, notes, and snippets.

@mnishiguchi
Last active August 29, 2015 14:26
Show Gist options
  • Select an option

  • Save mnishiguchi/cf09069906f6bfa7f485 to your computer and use it in GitHub Desktop.

Select an option

Save mnishiguchi/cf09069906f6bfa7f485 to your computer and use it in GitHub Desktop.
既存のDevise認証アプリに OmniAuth認証を追加する ref: http://qiita.com/mnishiguchi/items/f593fb9834e452c1925e
#...
# ==> OmniAuth
TWITTER_API_KEY = "T0ONiGrNuMNsKb5AyNC05mOpe"
TWITTER_API_SECRET = "FxrQ6ddvlVbIaUlvEm0xg4fgoK9ACmWWnkesdU60ck1vJFoBM8"
#...
#...
# ==> OmniAuth
config.omniauth :twitter, Rails.application.secrets.twitter_api_key,
Rails.application.secrets.twitter_api_secret
#...
$ bin/bundle
$ rake db:migrate
$ rails g controller omniauth_callbacks
# Ignore secrets
.env
.secret
= link_to "Log in with twitter", user_omniauth_authorize_path(:twitter)
$ rails g migration add_omniauth_to_users provider uid
#...
gem 'omniauth-twitter'
#...
= form_for(resource, as: resource_name, url: registration_path(resource_name)) do |f|
- if params[:from_omniauth_callback]
.alert.alert-danger Email address is required.
- else
= devise_error_messages!
.field.form-group
= f.text_field :username, autofocus: false, class: 'form-control', placeholder: "Username"
.field.form-group
= f.email_field :email, autofocus: false, class: 'form-control', placeholder: "Email"
- if f.object.password_required?
.field.form-group
= f.password_field :password, autocomplete: "off", class: 'form-control',
placeholder: "Password (#{@minimum_password_length} characters min)"
.field.form-group
= f.password_field :password_confirmation, autocomplete: "off", class: 'form-control',
placeholder: "Password confirmation"
.actions
= f.button "Create my account", class: "submit btn btn-success btn-lg btn-block",
data: { disable_with: "<i class='fa fa-spinner fa-spin'></i> Processing..." }
# 注意: Devise付きのアプリでOmniAuthを実装する場合は不要
# Rails.application.config.middleware.use OmniAuth::Builder do
# provider :twitter, Rails.application.secrets.twitter_api_key,
# Rails.application.secrets.twitter_api_secret
# end
class OmniauthCallbacksController < Devise::OmniauthCallbacksController
def all
# 認証データを元にデータベースでユーザーを探し、なければ作る。
user = User.from_omniauth(request.env["omniauth.auth"])
if user.persisted? # ユーザーがデータベース上に存在している。
sign_in_and_redirect user # ユーザーをsign_inする
set_flash_message(:notice, :success, kind: __callee__.to_s.capitalize) if is_navigational_format?
else # 何らかの理由でデータベースに保存されていない。
session["devise.user_attributes"] = user.attributes # 認証データを覚えておく。
redirect_to new_user_registration_url(from_omniauth_callback: "1") # ユーザーを新規登録ページに転送。
end
end
alias_method :twitter, :all
end
Rails.application.routes.draw do
#...
devise_for :users, controllers: { omniauth_callbacks: 'omniauth_callbacks' }
#...
end
production:
# ==> Rails
secret_key_base: <%= ENV["SECRET_KEY_BASE"] %>
# ==> OmniAuth
facebook_api_key: <%= ENV["FACEBOOK_API_KEY"] %>
facebook_api_secret: <%= ENV["FACEBOOK_API_SECRET"] %>
twitter_api_key: <%= ENV["TWITTER_API_KEY"] %>
twitter_api_secret: <%= ENV["TWITTER_API_SECRET"] %>
development:
# ==> Rails
secret_key_base: <%= ENV["SECRET_KEY_BASE_DEV"] %>
# ==> OmniAuth
facebook_api_key: <%= ENV["FACEBOOK_API_KEY"] %>
facebook_api_secret: <%= ENV["FACEBOOK_API_SECRET"] %>
twitter_api_key: <%= ENV["TWITTER_API_KEY"] %>
twitter_api_secret: <%= ENV["TWITTER_API_SECRET"] %>
test:
# ==> Rails
secret_key_base: <%= ENV["SECRET_KEY_BASE_TEST"] %>
class User < ActiveRecord::Base
#...
devise :database_authenticatable, :registerable, :confirmable,
:recoverable, :rememberable, :trackable, :validatable, :omniauthable
# OmniAuth認証データを元にデータベースでユーザーを探す。なければ新しく作る。
def self.from_omniauth(auth)
where(provider: auth.provider, uid: auth.uid).first_or_create do |user|
user.provider = auth.provider
user.uid = auth.uid
user.username = auth.info.nickname
# パスワード不要なので、パスワードには触らない。
end
end
# session["devise.user_attributes"]が存在する場合、それとparamsを組み合わせてUser.newできるよう、Deviseの実装をOverrideする。
def self.new_with_session(params, session)
if session["devise.user_attributes"]
new(session["devise.user_attributes"]) do |user|
user.attributes = params
user.valid?
end
else
super
end
end
# ログイン時、OmniAuthで認証したユーザーのパスワード入力免除するため、Deviseの実装をOverrideする。
def password_required?
super && provider.blank? # provider属性に値があればパスワード入力免除
end
# Edit時、OmniAuthで認証したユーザーのパスワード入力免除するため、Deviseの実装をOverrideする。
def update_with_password(params, *options)
if encrypted_password.blank? # encrypted_password属性が空の場合
update_attributes(params, *options) # パスワード入力なしにデータ更新
else
super
end
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment