Dongfeng Gu

【译】Devise的用法

- 4 mins

参考链接

原文链接

文章正文

Devise 能做什么

用户的认证功能对于新的Rails开发者来说是一件非常困难的事情, 而 Devise 是一个非常全面的用户认证gem,提供了以下一些重要的功能:

为什么使用 Devise

Deivse之所以如此受欢迎的主要原因,是因为它能够很快的帮助开发者建立起很全面的用户的认证系统,并且它非常稳定有专业的人员来做持续的维护工作。 在安全方面,Devise也包含了许多重要的功能来保证安全性,它可以自动加密/解密密码,重设密码等。总体来说,它可以很大程度的保证我们用户认证系统的安全性。

缺点

如果你想要复写Devise中的一些默认的功能,将会变的非常困难。比如说如果你想让一个用户使用用户名登录而不是邮件登陆,那么这个的难度可能跟你从头创建一个Auth的系统一样。 还有当你想要添加自己的参数到Devise的模块当中时,比如说把role属性添加到users模型当中,我们就需要来修改ApplicationController来吧role属性添加到白名单当中,这会感觉很奇怪因为正常来说我们应该修改的是对应模型本身的controller

实现/Devise实例

让我们现在开始集成Devise到我们的项目当中,首先我们需要到rubygems.org中获取最新的稳定版本,然后将相应的gem添加到我们项目的Gemfile当中。

gem 'devise', '~> 3.5', '>= 3.5.3'

然后我们运行bundle install来安装相应的文件,安装完成之后,我们可以运行生成器(generator):

rails generate devise:install

这将会创建以下两个文件

create  config/initializers/devise.rb
create  config/locales/devise.en.yml

在我们开始做其他任何事情之间,我们需要首先打开文件config/initializers/devise.rb然后将文件当中的默认邮件的属性修改成我们对应的邮件地址:

config.mailer_sender = 'please-change-me-at-config-initializers-devise@example.com'

修改为

config.mailer_sender = 'no-reply@gdf.name'

然后我们可以查看Devise在终端中打印出来的帮助文档

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

  1. Ensure you have defined default url options in your environments files. Here
     is an example of default_url_options appropriate for a development environment
     in config/environments/development.rb:

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

     In production, :host should be set to 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"

  3. Ensure you have flash messages in app/views/layouts/application.html.erb.
     For example:

       <p class="notice"><%= notice %></p>
       <p class="alert"><%= alert %></p>

  4. If you are deploying on Heroku with Rails 3.2 only, you may want to set:

       config.assets.initialize_on_precompile = false

     On config/application.rb forcing your application to not access the DB
     or load models when precompiling your assets.

  5. You can copy Devise views (for customization) to your app by running:

       rails g devise:views 

我们可以根据上面的提示来一步一步的完成Devise的配置

1.添加一个新的配置选项到config/environments/development.rb配置文件当中(如果是一个生产服务器那么你将会需要修改文件config/environments/production.rb)。在configure的代码块中,添加如下的代码:

# config/environments/development.rb
config.action_mailer.default_url_options = { host: 'localhost', port: 3000 }

2.请确认你有一个homepage, 如果没有的话你需要首先修改文件config/routes.rb如下:

# config/routes.rb

root to: 'pages#home'

其次你需要创建一个控制器文件app/controllers/pages_controllers.rb然后添加以下代码:

# app/controllers/pages_controller.rb

class PagesController < ApplicationController
  def home
  end
end

3.创建一个pages目录然后创建文件app/views/pages/home.html.erb,并将以下的代码写入到文件application.html.erb当中(在yield代码的上方):

<%#= app/views/layouts/application.html.erb %>

<p class="notice"><%= notice %></p>
<p class="alert"><%= alert %></p>

4.因为我们现在的Rails版本远超3.2,所以我们不需要做这一步的操作

5.使用Deivsegenerator创建视图(view)控件,在终端中运行命令rails g devise:views将会创建如下的文件:

app/views/devise/shared/_links.html.erb
app/views/devise/confirmations/new.html.erb
app/views/devise/passwords/edit.html.erb
app/views/devise/passwords/new.html.erb
app/views/devise/registrations/edit.html.erb
app/views/devise/registrations/new.html.erb
app/views/devise/sessions/new.html.erb
app/views/devise/unlocks/new.html.erb
app/views/devise/mailer/confirmation_instructions.html.erb
app/views/devise/mailer/password_change.html.erb
app/views/devise/mailer/reset_password_instructions.html.erb
app/views/devise/mailer/unlock_instructions.html.erb

上面的这些文件的创建将会给我们足够的代码来实现下列的功能:用户注册, 用户登录,用户编辑账户详情,用户重设密码和一些可以选择的功能,例如确认账号。

现在我们已经将所有的视图文件配置完毕,我们可以开始创建模型(model)文件,在终端中运行命令rails g devise User。这行代码将会创建一个模型(model)文件和一个迁移(migration)文件。迁移文件如下:

# db/migrate/20160115010323_devise_create_users.rb

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
      t.datetime :reset_password_sent_at

      ## Rememberable
      t.datetime :remember_created_at

      ## Trackable
      t.integer  :sign_in_count, default: 0, null: false
      t.datetime :current_sign_in_at
      t.datetime :last_sign_in_at
      t.string   :current_sign_in_ip
      t.string   :last_sign_in_ip

      ## 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, null: false # Only if lock strategy is :failed_attempts
      # t.string   :unlock_token # Only if unlock strategy is :email or :both
      # t.datetime :locked_at


      t.timestamps null: false
    end

    add_index :users, :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
  end
end

从上述的文件当中,我们可以看到Devise给我们的标准属性有些什么,例如emailpasswordDeivse也提供了相应的属性来跟踪记录用户的登录次数,还有许多其他的功能。默认情况下Devise注释掉了confirmable属性,如果你取消了注释,那么用户将会收到邮件来激活相应的账号才可以使用。这是一个很有用的功能,但是很多情况下确认的邮件将会发送到用户的垃圾收件箱当中并且会有一定的延迟。

现在让我们在终端中运行命令rake db:migrate这将会在数据库中创建user列表。最后使用命令rails s运行服务器,在浏览器中输入地址http://localhost:3000/users/sign_up你就可以注册账号然后使用注册好的账号访问http://localhost:3000/users/sign_in来登录系统。

有趣的功能

1.了解用户是否登录 将如下的代码添加到homepage当中:

<%#= app/views/pages/home.html.erb %>

<% if current_user %>
  <p>I'm signed in</p>
<% else %>
  <p>I'm not signed in</p>
<% end %>

首先登陆系统,你将会看到消息I'm signed in,然后打开一个匿名的浏览器窗口(chrome打开的方法为 MAC: cmd+shift+n Windows: ctrl+shift+n)访问主页你将会看到提示I'm not signed in。这是因为current_user这个属性是Devise的内置功能来查看一个用户是否登录。

2.强制用户登录

当我们想让强制用户登录之后才能查看某些页面时,我们可以使用方法authenticate_user!来保证用户必须登录了之后才能查看页面。在本项目中我们可以修改PagesControllers

# app/controllers/pages_controller.rb

class PagesController < ApplicationController
  def home
    authenticate_user!
  end
end

现在如果未登录的用户访问主页的时候将会自动跳转到登录界面,并且提示You need to sign in or sign up before continuing.

项目代码

链接

comments powered by Disqus
rss facebook twitter github youtube mail spotify instagram linkedin google pinterest medium vimeo