使用ruby on rails的好处之一就是有很多功能可以不用自己来实现,有很多开源的组件可以直接拿来用,达到项目的目的。
比如登陆安全验证,要让自己来写需要考虑很多:
1. session生命周期
2. 密码加密
3. 注册邮箱验证
等等。。。
此外还有各种麻烦的model操作,sign in, sign out, register, modify password, etc....
由于这部分业务逻辑相当统一,所以使用一个模板来搞定是很省事的,而ROR的一大优势就在于各种社区相当活跃,像用户验证这种应用广泛的组件也能找到很多,这里就采用了一个很成熟、功能强大的devise引擎来做介绍,注意rails版本最低得3.2。Github主页——https://github.com/plataformatec/devise
一、安装Devise
首先安装,在项目的Gemfile中,加上
gem 'devise'
接下来回到命令行,安装该Gem
bundle install
这样devise就安装好了,接下来就是将devise添加到项目中去
rails generate devise:install
如果在用户验证功能里需要用到邮件验证,则需要把下面的代码加到config/environments/development.rb 和 production.rb中
config.action_mailer.default_url_options = { :host => 'localhost:3000' }
另外在app/views/layouts/application.html.erb里可以加上下面的代码,用于显示登录过程中的各种警告信息
<%= notice %>
<%= alert %>
最后,还需要在路由文件添加root action并且添加view,这个root action就是登录成功后跳转的页面,比如可以这样添加
root 'welcome#index'
默认登录成功后进入welcome控制器下的index.html.erb这个view,当然可以需要按照具体情况修改
二、添加Model
既然作为用户验证,肯定组要验证的ID和Password,所以需要建立Model,使用devise来建立model,并且迁移数据库:
rails g devise user
rake db:migrate
这样一个默认的用户Model就建立起来了,然后添加模板
rails generate devise:views
devise会自动在view路径下添加用户验证所需要的各种view模板
下面做一些测试工作,在app/view/welcom/index.html.erb中写入如下代码:
Log In
<% if user_signed_in? %>
hello, <%= current_user.username %>! You are <%= current_user.role %>
<%= link_to('登出', destroy_user_session_path, :method => :delete) %>
<% else %>
<%= link_to('注册', new_registration_path(:user)) %>
<%= link_to('登录', new_session_path(:user)) %>
<% end %>
完成后可以使用rails server打开服务器,在浏览器输入http://localhost:3000/users/sign_in
可以看到一个功能完整的登录页面,并且有注册的链接,注册一个账户可以实现登录等功能,并且能够保持session会话。同时无论是wareshark抓包还是进入数据库,可以看到账户的密码都是加密的,安全性很好
当然这里可以发现登录的ID是邮件,很多时候我们用到的还是一个用户名而不是邮件,所以这里当然可以改成username。
首先给Model添加用户名属性,并且迁移数据库
rails generate migration add_username_to_users username:string:uniq
rake db:migrate
这样就成功将username属性添加到数据库中,并且设置为唯一。然后修改config/initializers/devise.rb文件,找到config.authentication_keys = [ :email ]这一行,改为下面这样:
config.authentication_keys = [ :username ]
由于username是新添加的属性,所以由于Rails健壮参数机制,还需要修改application_controller.rb文件,按照下面的格式修改:
class ApplicationController < ActionController::Base
before_action :configure_permitted_parameters, if: :devise_controller?
protected
def configure_permitted_parameters
devise_parameter_sanitizer.for(:sign_up) { |u| u.permit(:username, :password, :password_confirmation, :remember_me) }
devise_parameter_sanitizer.for(:sign_in) { |u| u.permit(:username, :password, :remember_me) }
devise_parameter_sanitizer.for(:account_update) { |u| u.permit(:username, :password, :password_confirmation, :current_password) }
end
end
然后修改views文件,把Email改为Username,比如sessions/new.html.erb可以这样改:
- <%= f.label :email %>
- <%= f.email_field :email %>
+ <%= f.label :login %>
+ <%= f.text_field :login %>
最后也是最重要的一步,如果出现email can't be blank的错误提示时,需要在app/models/user.rb里添加如下代码
protected
def email_required?
false
end
rails g migration remove_index
然后进入db/migrate可以找到新生城的文件,改为如下代码:
class RemoveIndex < ActiveRecord::Migration
def change
remove_index :users, :column => :email
end
end
然后只需rake db:migrate迁移数据库,这样应该就可以完成了。可以再次用浏览器验证一下
三、使用bootstrap风格的Devise
前面实现的用户验证界面还是挺简陋的,所以这里还是使用比较流行bootstrap前端框架美化一下
首先安装twitter-bootstrap-rails,我安装的是功能更加丰富的LESS样式,在Gemfile文件种添加依赖
gem "therubyracer"
gem "less-rails" #Sprockets (what Rails 3.1 uses for its asset pipeline) supports LESS
gem "twitter-bootstrap-rails"
bundle install
rails generate bootstrap:install less
接下来将app/assets/stylesheets/bootstrap_and_overrides.css.less文件,改为下面这样:
// Core variables and mixins
@import "twitter/bootstrap/variables.less";
@import "twitter/bootstrap/mixins.less";
// Reset and dependencies
@import "twitter/bootstrap/normalize.less";
@import "twitter/bootstrap/print.less";
//@import "twitter/bootstrap/glyphicons.less"; // Excludes glyphicons
// Core CSS
@import "twitter/bootstrap/scaffolding.less";
@import "twitter/bootstrap/type.less";
@import "twitter/bootstrap/code.less";
@import "twitter/bootstrap/grid.less";
@import "twitter/bootstrap/tables.less";
@import "twitter/bootstrap/forms.less";
@import "twitter/bootstrap/buttons.less";
// Components
@import "twitter/bootstrap/component-animations.less";
@import "twitter/bootstrap/dropdowns.less";
@import "twitter/bootstrap/button-groups.less";
@import "twitter/bootstrap/input-groups.less";
@import "twitter/bootstrap/navs.less";
@import "twitter/bootstrap/navbar.less";
@import "twitter/bootstrap/breadcrumbs.less";
@import "twitter/bootstrap/pagination.less";
@import "twitter/bootstrap/pager.less";
@import "twitter/bootstrap/labels.less";
@import "twitter/bootstrap/badges.less";
@import "twitter/bootstrap/jumbotron.less";
@import "twitter/bootstrap/thumbnails.less";
@import "twitter/bootstrap/alerts.less";
@import "twitter/bootstrap/progress-bars.less";
@import "twitter/bootstrap/media.less";
@import "twitter/bootstrap/list-group.less";
@import "twitter/bootstrap/panels.less";
@import "twitter/bootstrap/responsive-embed.less";
@import "twitter/bootstrap/wells.less";
@import "twitter/bootstrap/close.less";
// Components w/ JavaScript
@import "twitter/bootstrap/modals.less";
@import "twitter/bootstrap/tooltip.less";
@import "twitter/bootstrap/popovers.less";
@import "twitter/bootstrap/carousel.less";
// Utility classes
@import "twitter/bootstrap/utilities.less";
@import "twitter/bootstrap/responsive-utilities.less";
/*
*= require bootstrap_and_overrides
*/
这样就成功将bootstrap安装到rails项目中去,接下来再安装devise-bootstrap-views,这是一个将devise和bootstrap结合的views模板,安装方法和前面一样,在Gemfile里添加
gem 'devise-bootstrap-views'
然后bundle install,接下来生成模板,注意这里生成的模板可能会覆盖之前的views模板!!!!
rails g devise:views:bootstrap_templates
最后生成定制后的提示替换文件:
rails g devise:views:locale it