`

流行权限管理 gem Devise简介

阅读更多
update(2010-8-31)
如果,在2.3版本的rails上运行,发现如下类似错误
引用
$./script/generate devise:install
Couldn't find 'devise:install' generator

$./script/generate devise:views users

Couldn't find 'devise:install' generator


请参考devise在Rails 3和Rails 2的命令不一样

$ruby script/generate devise_install
$ruby script/generate devise User
$ruby script/generate devise_views




在我们之前的文章中我们已经介绍了一些登录和验证授权的解决方案,现在我们来介绍另外一个。最近,在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是在项目中是如何使用的。下面的截图是一个用Rails3.0写的简单的项目管理应用。 Devise将会添加一个User model和提供权限控制功能。



Devise可以很好的支持Rails 3 和Rails 2.3 在低的版本就不能支持了。而且,针对不同的Rails版本,我们需要选择不同的devise版本。Rails 3需要安装 Devise 1.1.rc0, 而rails2.3需要1.0.6。

那么,我们的项目是Rails3的就要应该把devise 的gem版本信息注明到gemfile里,如下:

	gem 'devise', '1.1.rc0' 


有了这个声明,我们就可以通过bundle来安装需要的gem和gem需要的依赖包了。

bundle install


接下来一步是通过generate安装devise相关代码。

$ rails generate devise_install
      create  config/initializers/devise.rb
      create  config/locales/devise.en.yml

===============================================================================

Some setup you must do manually if you haven't yet:

  1. Setup default url options for your specific environment. Here is an
     example of development environment:

       config.action_mailer.default_url_options = { :host => 'localhost:3000' }

     This is a required Rails configuration. In production is must be the
     actual host of your application

  2. Ensure you have defined root_url to *something* in your config/routes.rb.
     For example:

       root :to => "home#index"

===============================================================================


运行上面的命令会产生一些文件,包括config initializer下的初始化devise文件,和config/local下的i18n显示消息输出的文件。下面提示的是两个需要手动执行的操作,一个是为应用配置email host。另外,一个是在route下配置root的路由。演示项目中默认的根路由已经配置了,就不用再配。但devise发邮件用email的主机还需要配置,也很简单因为我们是开发环境,直接拷贝提示就行。

	config.action_mailer.default_url_options = { :host => 'localhost:3000' } 


这个配置的意思似乎把localhost做为接发邮件的主机,如果,项目上线,在生产环境就需要在production中把action_mailer的host配置成域名。

生成devise的User Model

Devise会使用User Model来控制和权限,而且,Devise提供了generator来生产User Model, 当然这个generato只是节省时间,并不是必须运行的,手动生成User model完全可以。

$ rails generate devise User
      invoke  active_record
      create    app/models/user.rb
      invoke    test_unit
      create      test/unit/user_test.rb
      create      test/fixtures/users.yml
      inject  app/models/user.rb
      create  db/migrate/20100412200407_devise_create_users.rb
       route  devise_for :users


运行generator会生成一个model文件,一个migration文件和一个devise_for的路由。我们下面将一个一个来看看这些文件的作用。
下面是generator生成的User Model:

	class User < ActiveRecord::Base  
	  # Include default devise modules. Others available are:  
	  # :token_authenticatable, :lockable, :timeoutable and :activatable  
	  # :confirmable  
	  devise :database_authenticatable, :registerable,   
	         :recoverable, :rememberable, :trackable, :validatable  
	  
	  # Setup accessible (or protected) attributes for your model  
	  attr_accessible :email, :password, :password_confirmation  
	end  



我们可以看到User model和普通的ActiveRecord的区别并不大,主要的差别是调用了devise方法,当然这也是配置的关键。Devise方法有很多的参数用来标识是否使用对应的功能模块。比如,我们在前文说过的:rememberable和:recoverable功能模块。所以,正如我们看到的,devise就是用这样简单的方式来配置是否使用相对应的功能模块。就是说,如果我们不想要确认password的功能,我们只是需要把对应的confirmable从这里删除就可以了。

同时,User类中还有attr_accessible方法,是用来描述可能用到的User表字段。也就是,如果我们需要在Model以为使用这个属性,那么,就要标识清楚是否需要只读还是读写权限。
接下来,我们看看生产的migration文件:

	class DeviseCreateUsers < ActiveRecord::Migration  
	  def self.up  
	    create_table(:users) do |t|  
	      t.database_authenticatable :null => false  
	      # t.confirmable  
	      t.recoverable  
	      t.rememberable  
	      t.trackable  
	      # t.lockable :lock_strategy => :failed_attempts, :unlock_strategy => :both  
	  
	      t.timestamps  
	    end  
	  
	    add_index :users, :email,                :unique => true  
	    # add_index :users, :confirmation_token,   :unique => true  
	    add_index :users, :reset_password_token, :unique => true  
	    # add_index :users, :unlock_token,         :unique => true  
	  end  
	  
	  def self.down  
	    drop_table :users  
	  end  
	end  


数据库的migration文件就很容易理解了,和普通的migration文件完全相同,标识user都会有什么字段。值得一提的是,表的字段和我们刚才的配置也有关系就是如果我们没有配置对应的功能模块,也就应该删除相对应的字段,和对应的索引。
Now that we’ve modified the migration to suit the modules we want to use we can run the database migration.
那么,修改完我们需要的migration文件就可以执行migration真正生成对应的数据库结构。通过运行下面命令生成:

rake db:migrate


接下来,我们看看generator在router.rb文件中的devise_for都产生了什么路由.我们可以通过rake routes查看:

    new_user_session   GET    /users/sign_in                 {:controller=>"devise/sessions", :action=>"new"}
          user_session POST   /users/sign_in                 {:controller=>"devise/sessions", :action=>"create"}
  destroy_user_session GET    /users/sign_out                {:controller=>"devise/sessions", :action=>"destroy"}
                       POST   /users/password(.:format)      {:controller=>"devise/passwords", :action=>"create"}
         user_password PUT    /users/password(.:format)      {:controller=>"devise/passwords", :action=>"update"}
     new_user_password GET    /users/password/new(.:format)  {:controller=>"devise/passwords", :action=>"new"}
    edit_user_password GET    /users/password/edit(.:format) {:controller=>"devise/passwords", :action=>"edit"}
                       POST   /users(.:format)               {:controller=>"devise/registrations", :action=>"create"}
                       PUT    /users(.:format)               {:controller=>"devise/registrations", :action=>"update"}
     user_registration DELETE /users(.:format)               {:controller=>"devise/registrations", :action=>"destroy"}
 new_user_registration GET    /users/sign_up(.:format)       {:controller=>"devise/registrations", :action=>"new"}
edit_user_registration GET    /users/edit(.:format)          {:controller=>"devise/registrations", :action=>"edit"}



稍微有点乱,当然,我们还是可以看出来,产生了如下路由:登录,登出,重置密码,注册,和修改。如果我们需要,所有这些路由都是可以配置的。
那么,有了这些路由我们就可以通过制定的描述,来访问对应的功能模块了。比如,我们应该通过访问/users/sign_up的路径来调用注册模块。




那么如果我们通过这个界面,我们完成注册,就会默认已经登录。这时,我们也可以通过/users/sign_out来登出。当然,如果这时我们再次试图通过访问/users/sign_in来登录,并输入刚才注册的用户名和口令。我们就会发现下面的错误:




这实际是一个Rails 3.0 beta 2的问题,如果,我们看到这个错误,可以通过修改 /config/initializers/cookie_verification_secret.rb中的secret key来修正。其中,secret key是用来验证登录cookies的。

	# Be sure to restart your server when you modify this file.  
	  
	# Your secret key for verifying the integrity of signed cookies.  
	# If you change this key, all old signed cookies will become invalid!  
	# Make sure the secret is at least 30 characters and all random,   
	# no regular words or you'll be exposed to dictionary attacks.  
	Rails.application.config.cookie_secret = '3b161f7668f938d1aeb73e1137964f8d5ebaf32b9173c2130ecb73b95b610702b77370640dce7e76700fb228f35f7865ab2a5ccd22d00563504a2ea9c3d8dffe'



我们需要做的就是在这个文件中删除相关描述,并且/config/application.rb文件中删除Rails.application的部分,如下:

	require File.expand_path('../boot', __FILE__)  
	require 'rails/all'  
	  
	Bundler.require(:default, Rails.env) if defined?(Bundler)  
	  
	module ProjectManage  
	  class Application < Rails::Application  
	    config.filter_parameters << :password  
	    config.cookie_secret = '3b161f7668f938d1aeb73e1137964f8d5ebaf32b9173c2130ecb73b95b610702b77370640dce7e76700fb228f35f7865ab2a5ccd22d00563504a2ea9c3d8dffe'  
	  end  
	end  



重启后,我们应该可以正常登录。



实际上,到目标我们已经完成了所有的验证权限的功能。接下来,我们可以进行一些改进。通常我们都愿意在页面上方显示用户是否已经登录的状态。如果登录就显示用户的一点信息,如果没有登录就显示登录和注册。
这样的需要很容易实现,我们可以在application的layout中添加对应的输出信息,以便在每个页面都可以看到同样的登录信息。如下:

	<div id="user_nav">  
	  <% if user_signed_in? %>  
	    Signed in as <%= current_user.email %>. Not you?  
	    <%= link_to "Sign out", destroy_user_session_path %>  
	  <% else %>  
	    <%= link_to "Sign up", new_user_registration_path %> or  
	    <%= link_to "Sign in", new_user_session_path %>  
	  <% end %>  
	</div> 



简单解释一下,这段显示登录信息的代码。这段代码主要是通过devise提供的方法实现,其中,判断是否登录是通过 user_signed_in? 如果登录了,就通过current_user来显示当前用户的email,而退出的路径是devise通过 destroy_user_session标识到/users/sign_out。同样,如果没有登录的话,可以通过 new_user_registration_path 和 new_user_session_path 分别表示注册和登录的路径。那么,当我们把代码写好,刷新页面就可以看到对应的信息了。




如果我们点击sign out的链接,我们应该看到注册和登录链接。




正如我们上面操作的,通过使用devise,添加很少的代码就可以拥有注册,登录,退出的功能。当然,devise还有更多的相关功能也相当容易上手使用。比如,重新设置密码的功能模块,也是在User的model里加上confirmable就可以拥有对应的功能。



最后,可能我们会想到一个问题。因为,所有的登录,权限相关的界面也都是devise生成的,那么,如果,我们希望页面风格和我们自己的网站的风格一致,怎么办?实际上,devise也考虑到了这一点,提供了很容易的定制devise的途径,我们将在下一篇中介绍。
















  • 大小: 36.2 KB
  • 大小: 44.4 KB
  • 大小: 60.2 KB
  • 大小: 39.3 KB
  • 大小: 41.9 KB
  • 大小: 41.3 KB
  • 大小: 40.4 KB
6
1
分享到:
评论
1 楼 nsd 2012-12-28  
不错!学习了

相关推荐

    nocms-admin-devise-pundit:宝石设置Devise和pundit,用于在nocms-admin中管理管理员和权限

    通过使用Devise处理所有身份验证和权限的Pundit,此Rails引擎将admins用户添加到NoCms Admin。 该gem称为nocms-admin-users,因为可以使用其他替代方法(例如cancancan),我们宁可不要使用通用名称。

    devise_google_authenticator:一个Devise扩展,允许您的应用使用Google的2FA移动应用

    将gem添加到您的Gemfile中(也不要忘记设计): 宝石``设计'' 宝石'devise_google_authenticator','0.3.16' 别忘了“捆绑安装” 设计安装(如果您尚未完成的话) 在设置Devise Google Authenticator之前,您...

    nukeTheCuke-devise-pundit

    Nukethecuke Devise权威该应用程序是由提供的 gem生成的。诊断程序此应用程序是用未知的配方共同构建的。 该应用程序是使用未知的首选项构建的,这些首选项无法协同工作。 如果应用程序无法按预期运行,请并包括以下...

    restrictable:Ruby on Rails的简单授权gem

    有限制的 使用管理Ruby on Rails的授权限制。 控制2或3种类型用户的动作的理想选择。 使用两个简单的控制器助手来限制用户角色对控制器执行特定操作: only_allow :cutom_user_role , to : :some_action_in_the_...

    collaborate:使用Ruby on Rails克隆流行的项目管理应用程序“ Basecamp”

    这是一个项目管理应用程序,具有流行应用程序Basecamp的许多功能。我与Qwasar硅谷的其他两个人共同开发了这个应用程序。 功能包括: 用户认证的帐户和安全登录 用户创建或参与多个项目的能力 项目中每个用户查看/...

    sample_admin_roles:货币 + 删除 + activeAdmin

    #Sample 管理员角色用户注册+访问限制+试错记录旨在实现管理屏幕#实现的功能1个用户,1个权限链接用户模型和角色模型注册为用户时-&gt; devise发送邮件,踩下URL完成认证(确认邮箱地址)设置默认角色管理ActiveAdmin &gt;...

    wdi_project_2:教育平台接受用户创建的课程

    使用gem Devise的用户身份验证和授权系统 带有宝石Toastr的自定义Flash通知 使用Gravatar API的用户头像 使用Mandrill API的交易电子邮件 使用Google,Github和LinkedIn进行Oauth登录 管理员用户使用ActiveAdmin gem...

    Rocket_Elevators_Information_System:火箭电梯信息系统

    火箭电梯信息系统 ... 为了达到这个目的,我们使用了Gem Devise,它照顾了用户创建和用户会话所需的所有控制器。 然后,我们使用RailsAdmin为我们提供了一个Backoffice接口来管理我们的数据,例如Employee表

    Elevators_media_streamer

    火箭电梯信息系统 ... 为了实现这一目标,我们使用了Gem Devise,它负责创建用户和创建用户会话所需的所有控制器。 然后,我们使用RailsAdmin为我们提供了一个Backoffice接口来管理我们的数据,例如Empl

    Rocket-Elevator-Foundation

    我们创建了一个包含多个表的... 为了实现这一目标,我们使用了Gem Devise,它负责创建用户和创建用户会话所需的所有控制器。 然后,我们使用RailsAdmin为我们提供了一个Backoffice接口来管理我们的数据,例如Empl

    Odyssey-Week-9-Rails

    火箭电梯信息系统 ... 为了实现这一目标,我们使用了Gem Devise,它负责创建用户和创建用户会话所需的所有控制器。 然后,我们使用RailsAdmin为我们提供了一个Backoffice接口来管理我们的数据,例如Empl

    zone1:1 区救援库

    身份验证:设计 gem + devise_harvard_auth_proxy 授权:acl9 Ajax上传工具:plupload 搜索: solr, 太阳黑子 标记:acts_as_taggable_on JavaScript 依赖项:jQuery、jQuery UI 分页:will_paginate 文件元...

    memes_rep:Ruby on Rails中的image(memes)存储库的示例应用程序

    Devise and Pundit管理和控制认证和授权; 设计引导程序; Rspec与FactoryBot一起进行测试; 使用的版本 Ruby 2.6.4 Rails 5.2.4 安装 使用代码: 使用下载资源库。 在命令行中,转到包含已下载文件的目录。 ...

    photogram-industrial-2

    我们将使用数据库索引和约束,高级关联访问器,范围,验证,无处不在的诸如link_to和form_with类的查看帮助器方法, form_with为了明智地使代码干燥,用于身份验证和密码重置电子邮件的Devise gem,明确授权访问每个...

    photogram-industrial

    我们将使用数据库索引和约束,高级关联访问器,范围,验证,无处不在的诸如link_to和form_with类的查看帮助器方法, form_with为了明智地使代码干燥,用于身份验证和密码重置电子邮件的Devise gem,明确授权访问每个...

    rich_cat_poor_cat_original

    此应用程序是使用提供的 gem 生成的。 诊断 这个应用程序是用未知的配方构建的。 这个应用程序是用不知道可以一起工作的首选项构建的。 如果应用程序未按预期运行,请并包含以下诊断信息: 我们还想知道您是否...

    ds-auth:数字服务SSO提供商

    对于Rails(或ruby)应用程序,已编写了 gem,以使集成消耗性应用程序更加容易: 展示了如何使用ds-auth-omniauth gem与Auth服务集成结构此应用程序是围绕属于不同组/组织的用户而构造的,并且由于他们属于这些组织...

    tdd-rails-pluralsight:使用RSpec,Capybara和Cucumber以及Pluralsight课程学习Rails的TDD

    用生成的目录测试新动作并显示动作测试创建动作测试索引和编辑操作测试更新和销毁操作安装和设置Devise gem 测试认证测试授权模型测试模型的责任测试验证测试协会测试实例方法测试数据库查询隔离测试嘲笑,存根和...

Global site tag (gtag.js) - Google Analytics