約3ヶ月のインターンを終えて
インターファームでの約3ヶ月インターンをしておりました平川です。
本日はインターン最終日ということで、ブログを書かせていただきます。
技術面としてgoogleアカウント認証についてと、インターンを経て考えたことの2つを書きたいと思います。
- googleアカウント認証について
googleアカウントだけでなく、TwitterやFacebookも似たような流れで実装できるという事で、自分なりのまとめとして書かせていただきます。
今回は管理画面にgoogleアカウント認証機能をつけたので、それに沿って書いていきます。
・googleアカウント認証を用いたログインの流れ
googleアカウントサインイン→webアプリケーションの許可→webアプリケーションへのログイン
Twitterのクライアントアプリの初回起動時、認証画面があるなあと思っていたのですが、あの過程は上記の流れと同様だと教えていただき、とても納得しました。
・実装ーRails
まずはgem の設定…
devise, omniauth,omniauth-google-oauth2を入れます
Gemfile
gem 'devise' gem 'omniauth' gem 'omniauth-google-oauth2'
ターミナルにて
$ bundle install $ rails g devise:install $ rails g devise admin $ rails g migration add_omniauth_to_users
deviseのインストールと、deviseを用いてAdminモデルを作成しました。
既存のコードを編集していることで起こったですが、
既にdeviseが入っていたため、deviseが再インストールになりました。
その結果、設定が追加され、一時的に管理画面がおかしくなってしまいました。
ここは $ rails g devise:install がいらなかったんですね。
$ rails g devise admin も既存のものがあったためいりませんでした。
続いて必要なカラムを追加します。
今回はuid,provider,nameです。
db/migrate/2014...add_omniauth_to_admins.rb
class AddOmniauthToAdmins < ActiveRecord::Migration def change add_column :admins, :uid, :string, null: false, default: ""; add_column :admins, :provider, :string, null: false, default: ""; add_column :admins, :name, :string add_index :admins, [:uid, :provider], unique: true end end
migrationを書き加えたため、上記を反映させるために
ターミナルにて
$ rake db:migrate
を実行します。
Sequel Proにて確認。カラムが追加されていました。
adminモデルでOmniAuthを有効にします。
app/models/admin.rb
class Admin < ActiveRecord::Base # Include default devise modules. Others available are: # :token_authenticatable, :confirmable, # :lockable, :timeoutable and :omniauthable devise :database_authenticatable, :registerable, :recoverable, :rememberable, :trackable, :validatable, :omniauthable end
カラム追加をしていたので、attr_accessible にuid,provider,nameを追加します。
# Setup accessible (or protected) attributes for your model attr_accessible :avatar, :email, :first_name, :first_name_kana, :last_name, :last_name_kana, :nickname, :password, :password_confirmation, :remember_me, :name, :provider, :uid
続いて、コントローラーを作成します。
app/controllers/admins/omniauth_callbacks_controller.rb
class Admins::OmniauthCallbacksController < Devise::OmniauthCallbacksController def google_oauth2 @admin = Admin.find_for_google_oauth2(request.env["omniauth.auth"]) if @admin!=nil set_flash_message(:notice, :success, :kind => "Google") if is_navigational_format? flash[:notice] = I18n.t "devise.omniauth_callbacks.success", :kind => "Google" sign_in @admin, :event => :authentication redirect_to admins_entries_path else session["devise.google_data"] = request.env["omniauth.auth"] redirect_to admins_entries_path end end end
redirectでは管理画面でログインしたときに表示されているページに設定しました。
request.env["omniauth.auth"]には、ハッシュとしてレスポンスされている情報が入っているとのことで…それを用いて
adminモデルに戻ってメソッドを設定します。
app/models/admin.rb
def self.find_for_google_oauth2(auth) admin = Admin.where(email: auth.info.email).first unless admin if Mail::Address.new(auth.info.email).domain == "interfirm.co.jp" admin = Admin.create!( name: auth.info.name, last_name: auth.info.last_name, first_name: auth.info.first_name, last_name_kana: "", first_name_kana: "", nickname: "", provider: auth.provider, uid: auth.uid, email: auth.info.email, password: Devise.friendly_token[0, 20]) end end admin end
今回、インターファームのアドレスのみが認証の対象となるようにしました。
最初は.domainなるものがある事を知らず、アドレスの最後から14文字が一致するかどうかという力技で判断しようとしていました…。
createする際は、バリデーションに沿って必要な値をとれるようにしました。
こちら側で指定したカラムについては空欄で設定しています。
エラー画面でハッシュ値がなにかを調べられるのは非常に便利ですね…!
googleのDeveloperConsoleにて、IDとSECRETが発行されるので、それを設定します。
ここはaplication.ymlにて環境変数として書きました。
config/initializers/devise.rb
# API key config.omniauth :google_oauth2, ENV['APP_ID'], ENV['APP_SECRET']
config/application.yml
APP_ID: "取得したID" APP_SECRET: "取得したSECRET"
まだ発行してなかったのでこの後入力しました…
最後に!サインインボタンを作りました。
app/views/admins/sessions/new.html.erb
<%=link_to 'Googleアカウントでサインイン', admin_omniauth_authorize_path(:google_oauth2),id:"g_Text" %>
よく見かけるボタン、コードが提供されているんですね。
- インターンを経て考えたこと
現在大学3年の私から見て考えてみた事です…。
・自分の知識や力
大学の勉強だけで身についた知識と力って、本当に少なくて、
エンジニアは自ら学んでいくことが大切だと思いました。
知らない事が沢山あることは分かりきった事ですが、いざ目の前にしてみないとその「知らない事」の大きさが分からないな、と。