- 在我们之前的文章中我们已经介绍了一些登录和验证授权的解决方案,现在我们来介绍另外一个。最近,在ruby社区Devise越来越广泛的被采用来解决维护权限和验证。Devise源于Warden,而warden是一个基于Rack的验证权限gem,不过,使用devise实际并不需要任何关于warden的知识。
- 如果你之前有一些其他类似的维护验证权限功能的gem的使用经验的话,你会发现Devise的和他们的不同之处在于,提供了从页面到model的实现。相比而言,例如Authlogic就只实现了丢与model层的实现,这时你就要自己去处理view层实现。而Devise是基于Rails 引擎开发的所以就可以同时提供controllers和view的实现。从功能角度来看,Devise提供了11个方面的在维护和验证权限过程的功能模块,这些模块都是可配置的。例如,其中Rememberable模块是使用cookie保存用户的登录信息,Recoverable是用来处理用户重置口令的。可定制的模块使用可以很容易的根据自己的业务需求配置对应的相应功能模块。
Devise : 简单引用
引用:
- gem 'devise'
- rails generate devise:install
- rails generate devise MODEL
我们可以用的变量:
- before_filter :authenticate_member!
- member_signed_in?
- current_member
- member_session
例如:
- class HomesController < ApplicationController
- before_filter :authenticate_user!, :except => [:show, :index]
- def index
- if !user_signed_in?
- return redirect_to '/account/sign_in'
- end
- return redirect_to "/admin/index" if current_user.admin
- end
- def show
- end
- end
创建view模型:
- rails generate devise:views users
1.gem
- gem 'devise'
2.routes
0> 运行
rails generate devise MODEL
- devise_for :users,:path => 'account',
- :controllers => {
- :registrations => :account,
- :sessions => :sessions
- }
1>db/migrate/......._devise_cretate_module
- class DeviseCreateUsers < ActiveRecord::Migration
- def change
- create_table(:users) do |t|
- ## Database authenticatable
- t.string :email, :null => false, :default => ""
- t.string :encrypted_password, :null => false, :default => ""
- ## Recoverable
- t.string :reset_password_token
- ## Rememberable
- 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
- t.string :name, comment:"姓名"
- t.string :phone, comment:"电话"
- t.text :bio,comment:"用户介绍"
- t.boolean :receive_announcements,comment:"是否接收网店邮件信息",default: true
- t.references :shop
- t.string :avatar_image_uid
- #增加用户权限
- t.boolean :admin, default: true
- ## 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
- t.timestamps
- end
- add_index :users, :shop_id
- add_index :users, [:shop_id , :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
2>app/models/module.rb
- class User < ActiveRecord::Base
- belongs_to :shop
- has_many :articles
- has_many :permissions , dependent: :destroy
- # Include default devise modules. Others available are:
- # :token_authenticatable, :confirmable,
- # :lockable, :timeoutable and :omniauthable
- devise :database_authenticatable, :registerable,
- :recoverable, :rememberable, :trackable, :validatable
- # Setup accessible (or protected) attributes for your model
- attr_accessible :id, :email, :password, :password_confirmation, :remember_me, :admin, :name, :shop_attributes, :phone ,:bio, :receive_announcements, :avatar_image_
- # attr_accessible :title, :body
- validates_presence_of :email
- validates :email, uniqueness: {scope: :shop_id}, format: {with: /\A[^@]+@([^@\.]+\.)+[^@\.]+\z/ }, if: :email_changed?
- validates_presence_of :password, if: :password_required?
- validates_confirmation_of :password, if: :password_required?
- validates_length_of :password, within: 6..20, allow_blank: true
- # before_create :ensure_authentication_token # 生成login token,只使用一次
- def is_admin?
- admin
- end
- def has_right?(resource_code)
- #暂时不需要校验首页权限,目前没有很多数据内容
- return true if self.is_admin?
- no_check_controller_array = ['account','users','kindeditor','photos','sessions',' ','oauth'] #不需要校验权限的控制器
- permissions = [all_resources.map(&:code) << no_check_controller_array].flatten
- resource_code.in?(permissions)
- end
- def all_resources
- Rails.cache.fetch("all_resources_for_user_#{id}") do
- all_resources = self.permissions.all.map(&:resource)
- end
- end
- def after_token_authentication # 登录后取消token
- self.authentication_token = nil
- end
- def password_required? # copy from devise
- !persisted? || !password.nil? || !password_confirmation.nil?
- end
- end
3.在controller中使用
- class HomesController < ApplicationController
- before_filter :authenticate_user!, :except => [:show, :index]
- def index
- if !user_signed_in?
- return redirect_to '/account/sign_in'
- end
- return redirect_to "/admin/index" if current_user.admin
- end
- def show
- end
- end
4.生成 Devise view
- rails generate devise:views users
5.rails s 运行试试
6. 重写 sessions
- class SessionsController < Devise::SessionsController
- # layout Proc.new { |controller|
- # if controller.request.headers['X-PJAX']
- # return false
- # end
- # case controller.action_name
- # when 'new'
- # return 'auth'
- # end
- # }
- def new
- super
- # 在这里添加其他逻辑
- end
- def create
- return super
- end
- end
7. 重写 registrations
- class AccountController < Devise::RegistrationsController
- def new
- super
- end
- def create
- super
- # email = UserMailer.create_confirm("mxbeijingmi@163.com")
- # UserMailer.deliver(email)
- # UserMailer.confirm("menxu_work@163.com").deliver
- # UserMailer.welcome_email(params[:user]).deliver
- UserMailer.send_mail(nil).deliver
- end
- def edit
- super
- end
- end