「Ruby on Rails Tutorial」のサンプルアプリをAngularJSとBootstrap3を使う形にして作成します。AngularJSを使ってユーザー登録機能を作成します。
(1)Railsユーザーモデルにhas_secure_passwordを使って暗号化パスワード認証の機能追加
1)概要
・bcriptを使ってパスワードをセキュアなハッシュとして保存できます。
・ユーザー作成時のパスワード存在チェック、パスワードの確認入力チェックのバリデーションが自動で追加されます。
・bcrypt-rubyをインストールをインストールする必要があります。
・テーブルに”password_digest”カラムを追加する必要があります。
2)設定手順
①bcrypt-rubyをインストール
$ vi Gemfile
gem ‘bcrypt’
$ bundle install
:
②usersテーブルに”password_digest”カラムを追加
$ rails generate migration add_password_digest_to_users password_digest:string invoke active_record create db/migrate/20150713044621_add_password_digest_to_users.rb
設定内容確認を確認します。
$ more db/migrate/20150713044621_add_password_digest_to_users.rb
class AddPasswordDigestToUsers
③マイグレーション実行
$ bundle exec rake db:migrate
④Userモデルに"has_secure_password"メソッド追加
"has_secure_password"によって"password"と"password_confirmation"属性が自動で追加され、存在チェックのバリデーションも設定されます。
$ vi app/models/user.rbclass User
3)Railsコンソールで動作確認
①ユーザー登録
2.0.0p247 :004 > test = User.create(name: "testuser4", email: "test4@example.com", password: "test4pass", password_confirmation: "test4pass")
=> #
②登録されたパスワードを表示
2.0.0p247 :005 > user = User.find_by(email: "test4@example.com")
2.0.0p247 :006 > user.password_digest
=> "$2a$..."
③誤ったパスワードで認証
2.0.0p247 :007 > user.authenticate("invalid")
=> false
④正しいパスワードで認証
2.0.0p247 :008 > user.authenticate("test4pass")
=> #
(2)AngularJSのパーシャルビューを使ってユーザー登録ページ作成
1)AngularJSのルート設定にnewを追加
$ vi app/assets/javascripts/mymodule.js.erb
myModule = angular.module('myModule', ['ui.bootstrap','ngRoute','ngResource']); myModule.config(function($routeProvider, $locationProvider) { $locationProvider.html5Mode(true); $routeProvider : .when("/users/new", { templateUrl: "" })
2)newページのテンプレートを追加
$ vi app/assets/templates/users/new.html.erb<div ng-controller="UsersNewCtrl" class="row"> <div class="col-md-6 col-md-offset-3"> <h1 class="text-center">Sign up</h1> <form name="userNewForm" novalidate> <div class="well"> <div class="form-group"> <label>name</label> <input name="name" class="form-control" ng-model="user.name" required /> </div> <div class="form-group"> <label>email</label> <input type="email" name="email" class="form-control" ng-model="user.email" required /> </div> <div class="form-group"> <label>password</label> <input type="password" name="password" class="form-control" ng-model="user.password" required /> </div> <div class="form-group"> <label>password_confirmation</label> <input type="password" name="password_confirmation" class="form-control" ng-model="user.password_confirmation" required /> </div> <button ng-click="submit()" class="btn btn-primary"> Create my account </button> </div> </form> </div> </div>
3)newページに対応するAngularJSコントローラ"UsersNewCtrl"を定義
$ vi app/assets/javascripts/mymodule.js.erbmyModule.controller("UsersNewCtrl", function($scope, userResource) { $scope.user = new userResource(); });
4)ホームページにnewページへのリンク追加
$ vi app/assets/templates/static_pages/home.html.erb<p class="text-center"> <a class="btn btn-large btn-primary" href="/users/new">Sign up now!</a> </p>
(3)AngularJSの$resourceサービスでPOST送信、Railsでデータ保存
1)AngularJSの$resourceサービスを使ってPOST送信
・"userResource"サービスを使ってPOST送信を行う関数を追加。
・ユーザー登録成功時は、ユーザーshowページへ遷移
$ vi app/assets/javascripts/mymodule.js.erbmyModule.factory("userResource", function($resource) { return $resource("/app/users/:id", { id: "@id" }, { 'create': { method: 'POST' }, : } ); }); mymodule.controller("UsersNewCtrl", function($scope, userResource, $location) { $scope.user = new userResource(); $scope.submit = function() { function success(response) { $location.path("/users/" + response.id); } function failure(response) { console.log("failure", response) } userResource.create($scope.user, success, failure); }; });
2)Railsコントローラを設定
$ vi app/controllers/users_controller.rbdef create @user = User.new(user_params) if @user.save render json: @user, status: :created, location: @user else render json: @user.errors, status: :unprocessable_entity end end private def user_params params.permit(:name:email,:password,:password_confirmation) end
3)CSRF対策
この状態でHTTP POSTリクエストを送信すると下記エラーが発生します。
Can't verify CSRF token authenticity
Completed 422 Unprocessable Entity in 1ms
上記を回避するためHTTPヘッダーにデフォルトでCSRFトークンを付与するように設定します。
$ vi app/assets/javascripts/mymodule.js.erbmyModule.config(function($httpProvider) { $httpProvider.defaults.headers.common['X-CSRF-Token'] = $('meta[name=csrf-token]').attr('content'); });
4)動作確認
ユーザー登録フォームからユーザー登録し、ユーザーshowページに遷移することを確認する。