2020年7月　gem Omniauthでgoogleログイン 認証



# 概要
Devise + omniauth + omniauth-google-oauth2 
でgoogle　ログインを実装する
色々な記事があったのですが、とりあえず忘れないように、備忘録としてのしておきます

### ＊注意＊

＊新規登録をしたあと2回目行こうを入力をせずにグーグルのボタンだけでログインできる機能であり、新規登録がGooleでできる訳ではないのであしからず。＊
その方法は、また別の時に解説します。


# 1. まずはGoogle Developers Consoleで登録

## 1-1.　下準備
こちらを参照してまずは、
クライアントID、クライアントシークレットを発行してください。
> [Google Maps API を使ってみた](https://qiita.com/Haruka-Ogawa/items/997401a2edcd20e61037)

## 1.2　Gemfile追加
クライアントID、クライアントシークレットが発行されたら　
Gemfileに追加します

```ruby:Gemfile
#省略
gem 'devise'
gem 'omniauth'
gem 'omniauth-google-oauth2'
...
```

```terminal:terminal
$ bundle install
```

## Deviseの設定

```terminal:terminal
$ rails g devise:install
```

# ユーザ認証用のテーブル作成
```terminal:termina
$ rails g devise user
```

```ruby:2020******_add_column_to_users.rb
class DeviseCreateUsers < ActiveRecord::Migration
  def change
    create_table(:users) do |t|
    add_column  :users,  :provider,  :string
    add_column  :users,  :uid,       :string
    add_column  :users,  :token,       :string
    add_column  :users,  :meta,       :string
  end
end
```

$ rake db:migrate

### Model修正

```ruby:app/models/user.rb
class User < ApplicationRecord
  devise :database_authenticatable, :registerable,
          :recoverable, :rememberable, :validatable, :confirmable,
          :omniauthable, omniauth_providers: %i(google)
...
...
...

  def self.find_for_google_oauth2(auth)
    user = User.where(email: auth.info.email).first

    unless user
      user = User.create(name:     auth.info.name,
                         provider: auth.provider,
                         uid:      auth.uid,
                         email:    auth.info.email,
                         token:    auth.credentials.token,
                         password: Devise.friendly_token[0, 20],
                         meta:     auth.to_yaml)
    end
    user
  end

end

```

:trackable, :omniauthableだけでOKです。deviseに新たに機能を持たせたいときは、そのとき新たに追記する方がスマートだと思います。今回は、とりあえずログインすることが目的なので、これでよい！

また、def self.find_for_google(auth)は、コールバックを受けた時にユーザが既にアプリケーションの中で認知されているかどうかを判断するメソッドです。後で使います。

### config修正
ここが他のサイトに乗っているのとは違うかったとこ！！！

```ruby:config/initializers/devise.rb
Devise.setup do |config|
    require 'devise/orm/active_record'
    config.omniauth :google_oauth2,
                    GOOGLE_CLIENT_ID="***sdps.apps.googleusercontent.com",
                    GOOGLE_CLIENT_SECRET="***********",
                    name: :google,
                    scope: %w(email) 
  end
```

GOOGLE_CLIENT_IDのとこがENV=['...']
となっているとこが多い。。
It's Simple!!
scopeについて、デフォルト(ここに記述しない状態)だとemailとprofileになります。ユーザ認証のための必須ではないため、emailだけにしちゃいましょう

### ログインボタンを設置するページ作る

```ruby:app/controllers/views/home.html.erb
= link_to image_tag('#.png'), omniauth_authorize_path(resource_name, provider)
```
### omniauth_callbacks_controller.rbを作成
app/controllers/usersディレクトリを作成して、omniauth_callbacks_controller.rbというコントローラーを作成します。

```ruby:omniauth_callbacks_controller.rb
class Users::OmniauthCallbacksController < Devise::OmniauthCallbacksController
  def google
    @user = User.find_for_google_oauth2(request.env['omniauth.auth'])

    if @user.persisted?
      flash[:notice] = I18n.t 'devise.omniauth_callbacks.success', kind: 'Google'
      sign_in_and_redirect @user, event: :authentication
    else
      session['devise.google_data'] = request.env['omniauth.auth']
      redirect_to new_user_registration_url
    end
  end
end
```

### サーバ起動
```terminal:terminal
$ rails s
```
で、サーバを起動し、
http://localhost:3000 にアクセスしてするとgoogle loginを押すと...



routes.rbでログイン後に遷移する先を記述していないのでrootに行ってますね。ログイン後、viewなどでcurrent_user.emailなどを表示させてみれば、ログインしているユーザのemailアドレスが表示されるかと思います。！