Rails+Deviseでgoogleログインするまで
Author: 水卜
Author: 水卜
deviseを使わないrailsプロジェクトは見たことがないくらい便利な認証系全部入りのgem
webサービスをやるときはできるだけパスワードを持ちたくないのでgoogle/facebook/twitterログインと合わせて使うことが多い。
Gemfile
gem 'devise'
bundle install
rails g devise:install
rails g devise user
できたマイグレーションファイルにこんな一画がコメントアウトされているが、外しておく。
## Trackable
t.integer :sign_in_count, default: 0, null: false
t.datetime :current_sign_in_at
t.datetime :last_sign_in_at
t.string :current_sign_in_ip
t.string :last_sign_in_ip
rails db:migrate
rails g devise:views users
rails g devise:controllers users
route.rb
devise_for :users, :controllers => {
:registrations => 'users/registrations',
:sessions => 'users/sessions'
}
devise_scope :user do
get "user/:id", :to => "users/registrations#detail"
get "signup", :to => "users/registrations#new"
get "login", :to => "users/sessions#new"
get "logout", :to => "users/sessions#destroy"
end
config/application.rb
require_relative 'boot'
require 'rails/all'
# Require the gems listed in Gemfile, including any gems
# you've limited to :test, :development, or :production.
Bundler.require(*Rails.groups)
module Myapp
class Application < Rails::Application
# Initialize configuration defaults for originally generated Rails version.
config.load_defaults 5.2
config.i18n.default_locale = :ja
# Settings in config/environments/* take precedence over those specified here.
# Application configuration can go into files in config/initializers
# -- all .rb files in that directory are automatically loaded after loading
# the framework and any gems in your application.
end
end
Gemfile
gem 'devise-i18n'
gem 'devise-i18n-views'
bundle install
rails g devise:views:locale ja
https://console.developers.google.com/project
開発環境ではdotenvでsecretとか管理するので入れておく。
Gemfile
gem 'dotenv-rails'
gem 'omniauth'
gem 'omniauth-google-oauth2'
bundle install
.env
GOOGLE_APP_ID=<your id>
GOOGLE_APP_SECRET=<your secret>
googleに貰ったデータを入れとく用。
もうuserモデルは作成済みなのでカラムを追加する。
rails g migration addColumnToUsers
db/migrate/hogehoge_add_column_to_users.rb
class AddColumnToUsers < ActiveRecord::Migration[5.2]
def change
add_column :users, :name, :string
add_column :users, :provider, :string
add_column :users, :uid, :string
add_column :users, :token, :string
add_column :users, :meta, :string
end
end
rails db:migrate
class User < ApplicationRecord
# Include default devise modules. Others available are:
# :confirmable, :lockable, :timeoutable, :trackable and :omniauthable
devise :database_authenticatable, :registerable,
:recoverable, :rememberable, :validatable, :trackable, :omniauthable, omniauth_providers: %i(google)
protected
def self.find_for_google(auth)
user = User.find_by(email: auth.info.email)
unless user
user = User.create(name: auth.info.name,
provider: auth.provider,
uid: auth.uid,
token: auth.credentials.token,
email: auth.info.email,
password: Devise.friendly_token[0, 20],
meta: auth.to_yaml)
end
user
end
end
config/initializers/devise.rb
Devise.setup do |config|
require 'devise/orm/active_record'
config.omniauth :google_oauth2,
ENV['GOOGLE_APP_ID'],
ENV['GOOGLE_APP_SECRET'],
name: :google,
scope: %w(email)
end
rails g controller home index
app/views/home/index.html.erb
<h1>Home#index</h1>
<p>Find me in app/views/home/index.html.erb</p>
<% if user_signed_in? %>
<%= current_user.email %>
<% end %>
<%= link_to 'Signin with Google', user_google_omniauth_authorize_path %>
config/routes.rb
Rails.application.routes.draw do
get 'home/index'
devise_for :users, :controllers => {
:registrations => 'users/registrations',
:sessions => 'users/sessions',
omniauth_callbacks: "users/omniauth_callbacks"
}
devise_scope :user do
get "user/:id", :to => "users/registrations#detail"
get "signup", :to => "users/registrations#new"
get "login", :to => "users/sessions#new"
get "logout", :to => "users/sessions#destroy"
end
# For details on the DSL available within this file, see http://guides.rubyonrails.org/routing.html
end
class Users::OmniauthCallbacksController < Devise::OmniauthCallbacksController
def google
@user = User.find_for_google(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
http://localhost:3000/home/indexにアクセスし、sign in with googleを押してみる。
ログインしたいアカウントを選択し、localhostにコールバックされる。
emailが無事表示されていればログイン成功。