Rails3+Devise+OmniAuthで簡単にログイン機能をつくる
以前,OmniAuthでログイン認証をつくっていたときに,Googleで調べてたらDeviseという簡単にログイン周りの機能を作成するGemがあるというので使ってみた.
目標はTwitterのアカウントでログインすること.
参考:devise と omniauth で facebook 認証をする手順
RailsでDeviseを使ってみた
[Rails] OmniAuth + Device で認証する
deviseでfacebook,twitter認証
インストール
まずはdeviseとomniauthをインストールする.
gem 'devise' gem 'omniauth' gem 'omniauth-twitter'
$ bundle install
deviseの初期化
deviseの初期化をする.
$ rails g devise:install create config/initializers/devise.rb create config/locales/devise.en.yml =============================================================================== Some setup you must do manually if you haven't yet: 1. Ensure you have defined default url options in your environments files. Here is an example of default_url_options appropriate for a development environment in config/environments/development.rb: config.action_mailer.default_url_options = { :host => 'localhost:3000' } In production, :host should be set to the actual host of your application. 2. Ensure you have defined root_url to *something* in your config/routes.rb. For example: root :to => "home#index" 3. Ensure you have flash messages in app/views/layouts/application.html.erb. For example: <%= notice %> <%= alert %> 4. If you are deploying Rails 3.1+ on Heroku, you may want to set: config.assets.initialize_on_precompile = false On config/application.rb forcing your application to not access the DB or load models when precompiling your assets. 5. You can copy Devise views (for customization) to your app by running: rails g devise:views ===============================================================================
出てきた指示どおりにconfig/environments/development.rbとapp/views/layouts/application.html.erbに追記して,rootとなるコントローラを作成しておく.
rails g devise:viewsを実行すると,認証のための画面などが作成される.
$ rails g devise:views [DEVISE] To select a encryption which isn't bcrypt, you should use devise-encryptable gem. invoke Devise::Generators::SharedViewsGenerator create app/views/devise/shared create app/views/devise/shared/_links.erb invoke form_for create app/views/devise/confirmations create app/views/devise/confirmations/new.html.erb create app/views/devise/passwords create app/views/devise/passwords/edit.html.erb create app/views/devise/passwords/new.html.erb create app/views/devise/registrations create app/views/devise/registrations/edit.html.erb create app/views/devise/registrations/new.html.erb create app/views/devise/sessions create app/views/devise/sessions/new.html.erb create app/views/devise/unlocks create app/views/devise/unlocks/new.html.erb invoke erb create app/views/devise/mailer create app/views/devise/mailer/confirmation_instructions.html.erb create app/views/devise/mailer/reset_password_instructions.html.erb create app/views/devise/mailer/unlock_instructions.html.erb
最後にOmniAuthでTwitter認証を使うために,TwitterのConsumer key等を設定する.
# config/initializers/devise.rb ... config.omniauth :twitter, 'Consumer Key', 'Consumer Secret' ...
これで,基本的な設定は完了.
認証用ユーザーの作成
認証用のユーザーを作成する.
$ rails g devise user [DEVISE] To select a encryption which isn't bcrypt, you should use devise-encryptable gem. invoke active_record create db/migrate/20130224******_devise_create_users.rb create app/models/user.rb invoke test_unit create test/unit/user_test.rb create test/fixtures/users.yml insert app/models/user.rb route devise_for :users
マイグレーションファイルを開いてOmniAuthを使うための変更を加える.
class DeviseCreateUsers < ActiveRecord::Migration def change create_table(:users) do |t| ## Database authenticatable #t.string :email, :default => "" #t.string :encrypted_password, :null => false, :default => "" ## Recoverable #t.string :reset_password_token #t.datetime :reset_password_sent_at ## Rememberable t.datetime :remember_created_at ## Trackable t.integer :sign_in_count, :default => 0 t.datetime :current_sign_in_at t.datetime :last_sign_in_at t.string :current_sign_in_ip t.string :last_sign_in_ip ## Confirmable #t.string :confirmation_token #t.datetime :confirmed_at #t.datetime :confirmation_sent_at #t.string :unconfirmed_email # Only if using reconfirmable ## Lockable #t.integer :failed_attempts, :default => 0 # Only if lock strategy is :failed_attempts #t.string :unlock_token # Only if unlock strategy is :email or :both #t.datetime :locked_at ## Token authenticatable #t.string :authentication_token ## Omniauthable t.string :username, :default => "" t.string :provider, :null => false, :default => "database" t.string :uid, :null => false, :default => "" t.timestamps end #add_index :users, :email, :unique => true #add_index :users, :reset_password_token, :unique => true #add_index :users, :confirmation_token, :unique => true #add_index :users, :unlock_token, :unique => true #add_index :users, :authentication_token, :unique => true end end
ここで大事なのが,Database authenticationに関する部分をコメントアウトしておくこと.デフォルトではemailを認証キーにしているが,Twitterの認証ではemailの情報が取得できないので,ユーザIDなど他のものをキーにして認証しないといけない.
ログイン,ログアウトへのリンクを作成
# root :to => "home#index" # app/view/home/index.html.erb <% if user_signed_in? %> <%= link_to 'ログアウト', destroy_user_session_path %> <% else %> <%= link_to "Twitterでログインする", user_omniauth_authorize_path(:twitter) %> <% end %>
はじめ,「Twitterでログインする」が出ていて,リダイレクト後に戻ってきて「ログアウト」が表示されていたらOK.
※モデルに後からフィールドを追加したくなったらrails g migrationを使えばよい
$ rails g migration add_omniauth_fields_to_users provider:string uid:string username:string
$ rake db:migrate
※WEBrickでSSLを使ってHTTPS通信する
Setup WEBrick to Serve SSL (HTTPS) as well as Non-SSL (HTTP) Traffic Side-by-Side
※日本語化
https://github.com/ir3/tatekoto/tree/master/config/locales
ディスカッション
コメント一覧
まだ、コメントがありません