sorceryを使ってログイン処理を作成してみる
( Ruby )Railsでsorceryを使ってログイン処理を実現してみることにします。
まずはMysqlを理由するのでそれに関連したプラグインもいれてきます。 Gemfileに必要なプラグインを記述
gem 'mysql2' gem 'sorcery' gem 'refinerycms' bundle install
DBの設定を行います
development: adapter: mysql2 database: gifanime pool: 5 timeout: 5000 encoding: utf8 # Warning: The database defined as "test" will be erased and # re-generated from your development database when you run "rake". # Do not set this db to the same as development or production. test: adapter: mysql2 database: gifanime pool: 5 timeout: 5000 encoding: utf8 production: adapter: mysql2 database: gifanime pool: 5 timeout: 5000 encoding: utf8
とりあえず、WEBサーバが動作するようにUnicornの設定をします。(内容はとりあえず、動作する目的で記述しているのであまりつっこまないでください)
# -*- coding: utf-8 -*- # ワーカーの数 worker_processes 2 # capistrano 用に RAILS_ROOT を指定 app_path = "/Users/nakajimadaichi/develop/gifanime/" working_directory app_path # ソケット listen '/tmp/unicorn.sock' # ログ rails_env = ENV['RAILS_ENV'] || 'production' if rails_env == 'production' stderr_path 'log/unicorn.log' stdout_path 'log/unicorn.log' else # stdout end # ダウンタイムなくす preload_app true before_fork do |server, worker| defined?(ActiveRecord::Base) and ActiveRecord::Base.connection.disconnect! old_pid = "#{ server.config[:pid] }.oldbin" unless old_pid == server.pid begin # SIGTTOU だと worker_processes が多いときおかしい気がする Process.kill :QUIT, File.read(old_pid).to_i rescue Errno::ENOENT, Errno::ESRCH end end end after_fork do |server, worker| defined?(ActiveRecord::Base) and ActiveRecord::Base.establish_connection end
前回の設定をちょっとかえてて、環境によってエラー出力をファイル出力か標準出力ぐらいのことしてます。 最後に起動してこんなふうに出力すればとりあえず完了。。
$ unicorn_rails -c config/unicorn.rb -E development -p 5000 I, [2012-02-12T19:35:14.296704 #4448] INFO -- : unlinking existing socket=/tmp/unicorn.sock I, [2012-02-12T19:35:14.297074 #4448] INFO -- : listening on addr=/tmp/unicorn.sock fd=5 I, [2012-02-12T19:35:14.298091 #4448] INFO -- : listening on addr=0.0.0.0:5000 fd=6 I, [2012-02-12T19:35:14.298290 #4448] INFO -- : Refreshing Gem list I, [2012-02-12T19:35:16.681432 #4448] INFO -- : master process ready I, [2012-02-12T19:35:16.694516 #4477] INFO -- : worker=0 ready I, [2012-02-12T19:35:16.698188 #4478] INFO -- : worker=1 ready
次はsorceryのインストールです。
# デフォルトのインストール rails generate sorcery:install # ユーザのリソースを作成 rails g scaffold User username:string email:string crypted_password:string salt:string # DBは婦負 rake db:migrate # セッション用のコントローラ作成 rails g controller UserSessions new create destroy
あとはsorceryが公開されているgithubのwikiをみて写経していきます。
# views/user_sessions/new.html.erb <%= form_for(@user) do |f| %> <% if @user.errors.any? %><% end %><%= pluralize(@user.errors.count, "error") %> prohibited this user from being saved:
<% @user.errors.full_messages.each do |msg| %>
- <%= msg %>
<% end %><%= f.label :username %>
<%= f.text_field :username %><%= f.label :email %>
<%= f.text_field :email %><%= f.label :password %>
<%= f.password_field :password %><%= f.label :password_confirmation %>
<%= f.password_field :password_confirmation %><%= f.submit %><% end %>
# models/user.rb class User < ActiveRecord::Base authenticates_with_sorcery! #attr_accessible :email, :password, :password_confirmation validates_length_of :password, :minimum => 3, :message => "password must be at least 3 characters long", :if => :password validates_confirmation_of :password, :message => "should match confirmation", :if => :password end
# controllers/user_sessions_controller.rb class UserSessionsController < ApplicationController before_filter :require_login skip_before_filter :require_login, :only => [:index, :new, :create] def new @user = User.new end def create respond_to do |format| if @user = login(params[:username],params[:password]) format.html { redirect_back_or_to(:users, :notice => 'Login successful.') } format.xml { render :xml => @user, :status => :created, :location => @user } else format.html { flash.now[:alert] = "Login failed."; render :action => "new" } format.xml { render :xml => @user.errors, :status => :unprocessable_entity } end end end def destroy logout redirect_to(:users, :notice => 'Logged out!') end end
# views/user_sessions/new.html.erbLogin
<%= render 'form' %> <%= link_to 'Back', user_sessions_path %>
# views/user_sessions/_form.html.erb <%= form_tag user_sessions_path, :method => :post do %><%= label_tag :username %>
<%= text_field_tag :username %><%= label_tag :password %>
<%= password_field_tag :password %><%= submit_tag "Login" %><% end %>
# config/routes.rb root :to => 'users#index' resources :user_sessions resources :users match 'login' => 'user_sessions#new', :as => :login match 'logout' => 'user_sessions#destroy', :as => :logout
# views/layouts/application.html.erbTutorial <%= stylesheet_link_tag "application" %> <%= javascript_include_tag "application" %> <%= csrf_meta_tags %><%= yield %><%= notice %>
<%= alert %>
# controllers/users_controller.rb class UsersController < ApplicationController before_filter :require_login skip_before_filter :require_login, :except => [:destroy] end
これでログイン可能になります。
このプラグインには他にもTwitter認証やfacebook認証もできるみたいで「external」をサブモジュールに 指定すればできるらしいです。
■参照URL ・Simple Password Authentication https://github.com/NoamB/sorcery/wiki/Simple-Password-Authentication
・外部連携してログインする方法 https://github.com/NoamB/sorcery/wiki/External