3
3

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

sorceryというRubyの認証便利gemを使う その1

Last updated at Posted at 2017-01-12

はじめに

Railsの認証系をなにか触ってみたく、sorceryというものがあるので何も考えずにサンプル通りに。
https://github.com/Sorcery/sorcery

sorceryは魔法という意味があるようです。魔法のような世界を体験してみます。

準備

% rails new sorcery-sample -d mysql
% tree -L 1
.
├── Gemfile
├── Gemfile.lock
├── README.md
├── Rakefile
├── app
├── bin
├── config
├── config.ru
├── db
├── lib
├── log
├── public
├── test
├── tmp
└── vendor

Simple Password Authenticationを試す

↓この通りにやる。
https://github.com/Sorcery/sorcery/wiki/Simple-Password-Authentication
Gemfileにsorceryを追加します。

Gemfile
gem 'sorcery'

sample通り、下記を実行するもエラー。

% rails g sorcery:install
/home/fukumura/.rbenv/versions/2.3.3/lib/ruby/gems/2.3.0/gems/bundler-1.13.6/lib/bundler/runtime.rb:94:in `rescue in block (2 levels) in require': There was an error while trying to load the gem 'uglifier'.
Gem Load Error is: Could not find a JavaScript runtime. See https://github.com/rails/execjs for a list of available runtimes.
Backtrace for gem load error is:
・・・

See https://github.com/rails/execjs for a list of available runtimes.
と言っているので、見てみるとruntimeをサポートしているのは下記。(2017/1/12時点)

    therubyracer - Google V8 embedded within Ruby
    therubyrhino - Mozilla Rhino embedded within JRuby
    Duktape.rb - Duktape JavaScript interpreter
    Node.js
    Apple JavaScriptCore - Included with Mac OS X
    Microsoft Windows Script Host (JScript)
    Google V8
    mini_racer - Google V8 embedded within Ruby

せっかくなのでwithin Ruby の 'therubyracer'取り込む。
Gemfileの'therubyracer'行をコメントアウト。

Gemfile
16 # See https://github.com/rails/execjs#readme for more supported runtimes
17 gem 'therubyracer', platforms: :ruby
% bundle install

generatorでアプリの雛形を作成。

% rails g sorcery:install
Running via Spring preloader in process 22607
Expected string default value for '--jbuilder'; got true (boolean)
     create  config/initializers/sorcery.rb
   generate  model User --skip-migration
Running via Spring preloader in process 22629
Expected string default value for '--jbuilder'; got true (boolean)
     invoke  active_record
     create    app/models/user.rb
     invoke    test_unit
     create      test/models/user_test.rb
     create      test/fixtures/users.yml
     insert  app/models/user.rb
     insert  app/models/user.rb
     create  db/migrate/20170111155833_sorcery_core.rb

dbに反映。

続いて、初期化ファイル、Userモデル、単体テストスタブ、およびデフォルトのマイグレーションを作成。

% rake db:migrate
rake aborted!
Mysql2::Error: Access denied for user 'root'@'localhost'

Tasks: TOP => db:migrate
(See full trace by running task with --trace)

MySQLの設定してなかった・・・ので作成。

MariaDB [(none)]> create user fukumura@localhost identified by 'testtest';
Query OK, 0 rows affected (0.00 sec)
MariaDB [(none)]> grant all on *.* to 'fukumura'@'localhost';
Query OK, 0 rows affected (0.00 sec)
MariaDB [(none)]> quit
Bye

fukumuraで入れることを確認。

root@ubuntu-xenial:~# mysql -u fukumura -p
Enter password:
Welcome to the MariaDB monitor.  Commands end with ; or \g.
Your MariaDB connection id is 53
Server version: 10.0.28-MariaDB-0ubuntu0.16.04.1 Ubuntu 16.04

Copyright (c) 2000, 2016, Oracle, MariaDB Corporation Ab and others.

Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.

MariaDB [(none)]>

無事入れることを確認したので、configを修正。

config/database.yml
12 default: &default
13   adapter: mysql2
14   encoding: utf8
15   pool: 5
16   username: fukumura
17   password: testtest
18   socket: /var/run/mysqld/mysqld.sock

データベース作成。

データベース名にハイフンがあるとエラーになるのでバッククォートでくくって実行します。

MariaDB [(none)]> CREATE DATABASE sorcery-sample_development CHARACTER SET utf8;
ERROR 1064 (42000): You have an error in your SQL syntax; check the manual that corresponds to your MariaDB server version for the right syntax to use near '-sample_development CHARACTER SET utf8' at line 1
MariaDB [(none)]> CREATE DATABASE `sorcery-sample_development` CHARACTER SET utf8;
Query OK, 1 row affected (0.00 sec)

dbに反映2。

% rake db:migrate
== 20170111155833 SorceryCore: migrating ======================================
-- create_table(:users)
  -> 0.0034s
-- add_index(:users, :email, {:unique=>true})
  -> 0.0032s
== 20170111155833 SorceryCore: migrated (0.0067s) =============================

generatorで雛形作成。

% rails g scaffold user email:string crypted_password:string salt:string --migration false
Running via Spring preloader in process 23067
Expected string default value for '--jbuilder'; got true (boolean)
     invoke  active_record
   conflict    app/models/user.rb
 Overwrite /home/fukumura/projects/sorcery-sample/app/models/user.rb? (enter "h" for help) [Ynaqdh] n
       skip    app/models/user.rb
     invoke    test_unit
  identical      test/models/user_test.rb
   conflict      test/fixtures/users.yml
   Overwrite /home/fukumura/projects/sorcery-sample/test/fixtures/users.yml? (enter "h" for help) [Ynaqdh] n
       skip      test/fixtures/users.yml
     invoke  resource_route
      route    resources :users
     invoke  scaffold_controller
     create    app/controllers/users_controller.rb
     invoke    erb
     create      app/views/users
     create      app/views/users/index.html.erb
     create      app/views/users/edit.html.erb
     create      app/views/users/show.html.erb
     create      app/views/users/new.html.erb
     create      app/views/users/_form.html.erb
     invoke    test_unit
     create      test/controllers/users_controller_test.rb
     invoke    helper
     create      app/helpers/users_helper.rb
     invoke      test_unit
     invoke    jbuilder
     create      app/views/users/index.json.jbuilder
     create      app/views/users/show.json.jbuilder
     create      app/views/users/_user.json.jbuilder
     invoke  assets
     invoke    coffee
     create      app/assets/javascripts/users.coffee
     invoke    scss
     create      app/assets/stylesheets/users.scss
     invoke  scss
     create    app/assets/stylesheets/scaffolds.scss

user_params部分を修正。

app/controllers/users_controller.rb
   def user_params
     params.require(:user).permit(:email, :password, :password_confirmation)
   end

_form.html.erbを修正。

<%= form_for(user) do |f| %>
  <% if user.errors.any? %>
    <div id="error_explanation">
      <h2><%= pluralize(user.errors.count, "error") %> prohibited this user from being saved:</h2>

      <ul>
      <% user.errors.full_messages.each do |message| %>
        <li><%= message %></li>
      <% end %>
      </ul>
    </div>
  <% end %>

  <div class="field">
    <%= f.label :email %>
    <%= f.text_field :email %>
  </div>

  <div class="field">
     <%= f.label :password %><br />
     <%= f.password_field :password %>
  </div>
  <div class="field">
     <%= f.label :password_confirmation %><br />
     <%= f.password_field :password_confirmation %>
  </div>

  <div class="actions">
    <%= f.submit %>
  </div>
<% end %>

ログイン後のセッション情報周りの機能も作らないといけないのでそれも作成。

% rails g controller UserSessions new create destroy
Running via Spring preloader in process 23111
Expected string default value for '--jbuilder'; got true (boolean)
Expected string default value for '--helper'; got true (boolean)
Expected string default value for '--assets'; got true (boolean)
     create  app/controllers/user_sessions_controller.rb
      route  get 'user_sessions/destroy'
      route  get 'user_sessions/create'
      route  get 'user_sessions/new'
     invoke  erb
     create    app/views/user_sessions
     create    app/views/user_sessions/new.html.erb
     create    app/views/user_sessions/create.html.erb
     create    app/views/user_sessions/destroy.html.erb
     invoke  test_unit
     create    test/controllers/user_sessions_controller_test.rb
     invoke  helper
     create    app/helpers/user_sessions_helper.rb
     invoke    test_unit
     invoke  assets
     invoke    coffee
     create      app/assets/javascripts/user_sessions.coffee
     invoke    scss
     create      app/assets/stylesheets/user_sessions.scss

viewファイル。

app/views/user_sessions/new.html.erb
<h1>Login</h1>

<%= render 'form' %>
<%= link_to 'Back', user_sessions_path %>
app/views/user_sessions/_form.html.erb
<%= form_tag user_sessions_path, :method => :post do %>
 <div class="field">
   <%= label_tag :email %><br />
   <%= text_field_tag :email %>
 </div>
 <div class="field">
   <%= label_tag :password %><br />
   <%= password_field_tag :password %>
 </div>
 <div class="actions">
   <%= submit_tag "Login" %>
 </div>
<% end %>

セッションコントローラー

app/controllers/user_sessions_controller.rb
class UserSessionsController < ApplicationController
 def new
   @user = User.new
 end

 def create
   if @user = login(params[:email], params[:password])
     redirect_back_or_to(:users, notice: 'Login successful')
   else
     flash.now[:alert] = 'Login failed'
     render action: 'new'
   end
 end

 def destroy
   logout
   redirect_to(:users, notice: 'Logged out!')
 end
end

ルーティングの設定。

config/routes.rb
root :to => 'users#index'
resources :user_sessions
resources :users

get 'login' => 'user_sessions#new', :as => :login
post 'logout' => 'user_sessions#destroy', :as => :logout

サンプルにはナビゲーションまでご丁寧にあったのでそれも実装。

app/views/layouts/application.html.erb
<!DOCTYPE html>
<html>
 <head>
   <title>Tutorial</title>
     <%= stylesheet_link_tag    "application" %>
     <%= javascript_include_tag "application" %>
     <%= csrf_meta_tags %>
 </head>
 <body>

 <div id="nav">
   <% if current_user %>
     <%= link_to "Edit Profile", edit_user_path(current_user.id) %>
     <%= link_to "Logout", :logout, method: :post %>
   <% else %>
     <%= link_to "Register", new_user_path %> |
     <%= link_to "Login", :login %>
   <% end %>
 </div>
 <div>
   <p id="notice"><%= flash[:notice] %></p>
   <p id="alert"><%= flash[:alert] %></p>
 </div>
 <%= yield %>

 </body>
</html>

sample通りにやってみた。ちゃんと動いた。

ソースはこちら。https://github.com/fukumura/sorcery-sample

3
3
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
3
3

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?