Railsでfacebook認証の実装方法（初心者向け）簡単！

#初めに
ポートフォリオを作成する際に、『deviseでのログイン方法』＋『facebook認証を利用したログイン方法』を実装したのでメモを残します。

#環境
・Ruby '2.3.8'
・Rails '5.2.3'

#deviseの導入
```ruby:Gemfile
gem 'devise'
```

```
$ bundle install
$ rails g devise:install
$ rails g devise user
$ rails db:migrate
```

以上でdeviseの導入は完了です。

#カラムの追加
usersテーブル以下のカラムを追加します。
　1. uid　＝　facebookログイン時に取得してくるデータ
　2. provider = ログインに使用したプロバイダーを取得する（facebook、google、line等)

```
$ rails g migration AddColumnsToUsers uid:string provider:string
```

作成された`db/migrate/xxxxxxxxxxxadd_columns_to_users.rb`を確認し、内容に間違えがなければ`rails db:migrate`を実行します。

#facebook側の設定
1.[facebook](https://developers.facebook.com/apps)に接続し、新しいアプリを追加します。
表示名はアプリの名前です。
2.設定>ベーシックを選択後、ページの一番下のプラットフォームを追加するをクリックし、ウェブサイトを選択する。
サイトURLに`http://localhost:3000/`を入力する。
3.プロダクト＋をクリックし、Facebookログインを選択する。
対応アプリを聞かれるので、ウェブを選択する。
4.有効なOauthリダイレクトURIに`https://localhost:3000/users/auth/facebook/callback`を記載する。<img width="1439" alt="スクリーンショット 2019-08-25 1.16.57.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/453605/f1265fd6-df7c-5d1c-c061-08686fb5e482.png">

#認証系gemの導入
```ruby:Gemfile
gem 'omniauth'
gem 'omniauth-facebook'
```

```
$ bundle install
```
#Rails側の設定
##1.config設定
`config/insitializers/devise.rb`の一番下に以下を記述します。

```ruby:devise.rb
 config.omniauth :facebook, FACEBOOK_ID='aaaaaaaa', FACEBOOK_SECRET_KEY='bbbbbbbbb'
end
```

aaaaaaaaにはfacebook_IDを入力します。
bbbbbbbbにはfacebook_secret_keyを入力します。
IDとsecret_keyは設定>ベーシックで確認出来ます。
**※IDがアプリID、secret_keyがapp Secretです。**
<img width="1439" alt="スクリーンショット 2019-08-25 1.32.33.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/453605/dbb80535-b0d8-cc9d-09df-26b9142cc3d8.png">

##2.deviseにメソッド追加
`app/model/user.rb`を以下の様に変更します。

```ruby:user.rb
devise :database_authenticatable, :registerable,
         :recoverable, :rememberable, :validatable, :omniauthable
```
##3.Userモデルにfindメソッド実装
先ほどの`app/model/user.rb`を以下の記述をに追加します。

```ruby:user.rb
  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,
        email:    auth.info.email,
        password: Devise.friendly_token[0, 20]
      )
    end
    user
  end
end
```
この記載により、facebook認証実施済みユーザはそのままログイン出来る様になります。
facebook認証する際には、uidとproviderとemailとpasswordを取得してきます。
**パスワードはDevise.friendly_token[0, 20]により生成されます。そのパスワードはランダムに決まった数字20桁の為、登録したユーザには分かりません。**

##4.コールバック処理の実装
`app/controllers`に`users`ファイルを作成し、その中に`omniauth_callbacks_controller.rb`を作成します。
そして、以下の記述をします。

```ruby:omniauth_callbacks_controller.rb
class Users::OmniauthCallbacksController < Devise::OmniauthCallbacksController
  def facebook
    callback_from :facebook
  end

  private
  def callback_from(provider)
    provider = provider.to_s

    @user = User.find_for_oauth(request.env['omniauth.auth'])

    if @user.persisted?
      flash[:notice] = I18n.t('devise.omniauth_callbacks.success', kind: provider.capitalize)
      sign_in_and_redirect @user, event: :authentication
    else
      session["devise.#{provider}_data"] = request.env['omniauth.auth']
      redirect_to new_user_registration_url
    end
  end

end
```
##5.ルーティング設定
`config/route.rb`に以下を追加します。

```ruby:route.rb
devise_for :users, controllers: { omniauth_callbacks: 'users/omniauth_callbacks' }
```

##6.リンクの記載
リンクは以下の様になります。

```ruby:new.html.erb
<%= link_to "facebook", user_facebook_omniauth_authorize_path  %>
```

#参考資料
[【開発メモ】RailsアプリでFacebookログインの認証機能を実装させる方法](https://freesworder.net/rails-facebook/)
[Railsでomniauth(google/facebook/)実装方法](https://qiita.com/hidepino/items/a1eb9d2f32ce33389f20)

#注意事項
facebookはHTTPSしか有効なOAuthリダイレクトURIに登録出来ません。
なので、開発環境なら誰でも使用出来ますがデプロイ後はHTTPSに変更する必要があります。

#体験談
私はgoogle、facebook、LINEの認証を実装しました。
googleは特に変更することなくデプロイ後も使用できます。
LINEはemail情報を取得するのに申請を出さなければいけない為、前準備に時間が掛かります(約3週間)
twitterも同様に申請が必要です。

デプロイすることを考慮するとgoogle認証が一番簡単でした。

#最後に
たったこれだけでfacebookでの認証が出来る様になります。
よければ参考にしてみて下さい。