
この記事は devise、omniauth-facebook、omniauth-twitterのGemを使って、メールとFacebookとTwitterでログイン機能を作ります。
まずはFacebookとTwitter側の設定から始めます。
Facebook側の設定
アプリを作成URL:https://developers.facebook.com/apps/create


新規アプリを作成してから「Facebookログイン」を設定します。

Facebookログインの設定画面ではまず public_profile
をAdvanced Accesssに切り替えて、それから「有効なOAuthリダイレクトURI」に <ホスト>/users/auth/facebook/callback
を入力します。

設定のベーシック画面でアプリのデータ使用状況の確認を完了を開始してから、アプリID
とアプリシークレット
をコピーしときます。

App detailsの設定の例は以下のようで、注意するところは二つ:
Enable Sign in with Twitter
をチェック
Callback URLs
に<ホスト>/users/auth/twitter/callback
を入力

デフォルトはメール情報を取得できなくて、メール情報を取得するにはPermissionsタブでRequest email address from users
をチェックして保存する必要があります。

最後は Keys and tokensタブで API key
とApi secret key
をコピーしておきます。

ここまではFacebookとTwitterの設定が完了なので、次はソースコードに着手します!
Gem導入
Copy
Gemfile
1
2
3
4
5
| gem 'devise'
gem 'devise-i18n' # 英語で使うなら不要
gem 'omniauth-rails_csrf_protection'
gem 'omniauth-facebook'
gem 'omniauth-twitter'
|
deviseのインストール
User
というモデルでdeviseを作る
カスタムのため、コントローラとビューと翻訳ファイルをコピーしておく
deviseのコントローラ作成
Copy
1
| rails g devise:controllers users
|
deviseのビュー作成
Copy
1
| rails g devise:views users
|
deviseの翻訳ファイル作成
Copy
1
| rails g devise:it8n:locale ja
|
ビューのフォルダ名はdevise
ではなくusers
などであれば、deviseの翻訳ファイルを編集する必要があります
Copy
config/locales/devise.views.ja.yml
1
2
3
4
5
| ja:
# ・・・省略
devise: &devise
# ・・・省略
users: *devise
|
deviseの設定
Copy
config/initializers/devise.rb
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
| config.omniauth :facebook,
ENV['FACEBOOK_APP_ID'],
ENV['FACEBOOK_APP_SECRET'],
{
scope: 'email',
image_size: 'large',
locale: 'en' # 英語で情報を取得
}
config.omniauth :twitter,
ENV['TWITTER_CONSUMER_API_KEY'],
ENV['TWITTER_CONSUMER_API_SECRET_KEY'],
{
image_size: 'original',
lang: 'en' # 英語で情報を取得
}
config.mailer_sender = 'LANGMEMO <notification@langmemo.com>' # deviseから送信するメールのアドレス
config.scoped_views = true # カスタマイズのビューを使う場合
|
アカウント登録、ログイン、ログアウトなどのURLヘルパー:
Copy
slim
1
2
3
| = link_to 'アカウント登録', new_user_registration_path
= link_to 'ログイン', new_user_session_path
= button_to 'ログアウト', destroy_user_session_path, method: :delete, 'data-turbo': false
|
アカウント登録時のカスタムフィールドを追加する場合
Copy
config/routes.rb
1
2
3
| devise_for :users, controllers: {
registrations: 'users/registrations'
}
|
Copy
app/controllers/users/registrations_controller.rb
1
2
3
4
5
6
7
8
9
10
11
12
13
14
| before_action :configure_sign_up_params, only: [:create]
before_action :configure_account_update_params, only: [:update]
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])
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])
end
|
アカウント情報更新時に現在のパスワードを無くする場合
Copy
app/controllers/users/registrations_controller.rb
1
2
3
4
5
| protected
def update_resource(resource, params)
resource.update_without_password(params)
end
|
アカウント登録して、メールで確認URLをクリックしてから自動ログインしたい場合
Copy
config/routes.rb
1
2
3
| devise_for :users, controllers: {
confirmations: 'users/confirmations'
}
|
Copy
app/controllers/users/confirmations_controller.rb
1
2
3
4
5
6
7
8
| protected
# The path used after confirmation.
def after_confirmation_path_for(resource_name, resource)
# super(resource_name, resource)
sign_in(resource)
root_path
end
|
Deviseのフォームで送信した後のリダイレクトにturbo
をfalse
にしたい場合
html: { 'data-turbo': false }
を入れる
Copy
sessions/new.html.erb
1
2
| <%= form_for(resource, as: resource_name, url: session_path(resource_name), html: { 'data-turbo': false }) do |f| %>
|
ここまではメールでアカウント登録、ログインができるようになりました。
Copy
config/routes.rb
1
2
3
| devise_for :users, controllers: {
omniauth_callbacks: 'users/omniauth_callbacks'
}
|
Copy
app/models/user.rb
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
| devise :database_authenticatable, :registerable, :recoverable,
:rememberable, :validatable, :confirmable, :trackable,
:omniauthable # これを追加
class << self
def find_for_oauth(auth)
@user = User.find_or_initialize_by(uid: auth.uid, provider: auth.provider)
assign_info(auth)
attach_image(auth.info.image) if auth.info.image
@user.skip_confirmation!
@user.save!
@user
rescue StandardError => e
e.message
end
def assign_info(auth)
@user.uid = auth.uid
@user.provider = auth.provider
@user.name = auth.info.name
@user.email = auth.info.email
@user.password = Devise.friendly_token[0, 20]
end
def attach_image(image_url)
@user.image.attach(io: URI.parse(image_url).open, filename: "user_#{@user.id}_image")
# ファイルの一番上に require 'open-uri' が必要
end
end
|
Copy
app/controllers/users/omniauth_callbacks_controller.rb
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
| def facebook
callback_from :facebook
end
def twitter
callback_from :twitter
end
private
def callback_from(provider)
@user = User.find_for_oauth(request.env['omniauth.auth'].delete_if { |k, _v| k == 'extra' })
if @user.instance_of?(User)
flash[:notice] = t('devise.omniauth_callbacks.success', kind: provider.to_s.capitalize)
sign_in_and_redirect @user, event: :authentication
else
session["devise.#{provider}_data"] = request.env['omniauth.auth']
redirect_to new_user_registration_path, alert: @user
end
end
|
Updated by Yuto at 2023-05-09 21:05