Dongfeng Gu

【译】Rails 用户认证(Authen)

- 2 mins

参考链接

原文链接

文章正文

为什么要从用户认证(Authentication)开始

当我们决定先创建什么功能的时候,一个重要的依据就是功能之间的依赖性(dependencies)。依赖性的意思就是指不同功能之间的需求程度。功能A的依赖性高就是指有很多其他的功能需要这个功能A。下面让我们看一看我们所创建的需求表:

functional requirements

仔细阅读需求表,你将会发现几乎有一半的需求都跟User有关,所以我们将会从User的功能开始。如果你从其他的功能(比如Post)开始,那么我们将会需要在实现User的功能的时候回到Post当中来重构Post的代码。

从另一个方面来看,当我们查看数据库的schema.rb文件时,我们将会发现数据库中有许多其他的表单将user_id设为了外键(foreign key)。这是一个非常好的信号用来表示User这个表的依赖程度。所以说我们将会首先开始来创建User模型。

使用Devise还是从头开始创建用户认证系统

我编写过很长一段时间的程序。到目前为止,只有两个应用程序我是从头开始创建用户认证系统而不是使用现有的用户认证系统库,类似于Deivse。而且这两个例外的应用程序还是因为它有特定的需求,需要集成微软的ActiveDirectory认证引擎,所以才我从头创建用户的认证系统。

我个人的观点认为我们应该使用像Devise这样,经过充分测试并且会有人员长期维护的库来创建一些功能,而不是从头开始创建。在接下来的教程当中,我将会介绍如何集成Devise的每一个步骤,但我并不会介绍Devise这个gem本身的内容,我已经写过一篇博客Devise的用法用来介绍有关Devise本身的内容,读者可以点进链接进行参。

实现用户认证

我们本来可以从创建模型的spec测试开始,但是我并不想给一些已经做过充分测试的功能再写一些重复的测试。Devise已经有一个非常详细与综合的测试系统,你可以查看测试链接

在我们创建新的功能之间,有一个很重要的地方需要注意的就是,我们不能在mater分支上面直接修改代码,我们需要首先创建一个新的分支:

git checkout -b add-auth

将我们正在做的工作与master分支区分开来将是非常重要的,因为这样可以解决如下这种情况,当我们正在工作的时候,我们突然有另外一个非常紧急的功能需要实现,比如说修复一个错误,如果说我并没有将我现在工作放到另外一个分支当中,那么我将需要做:

现在让我们安全的在另外一个独立的分支当中开始工作,将gem信息添加到Gemfile.rb当中:

# Gemfile

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

在运行了命令bundle之后,我们可以运行安装器:

rails generate devise:install

首先让我们在config/initializers/devise.rb中来更新默认的mailer_sender设置,这将可以保证认证邮箱的发件人是我们而不是默认的地址。

# config/initializers/devise.rb

config.mailer_sender = 'team@dailysmarty.com'

现在让我们来一步一步的进行配置:

更新本地的邮件服务器

# config/environments/development.rb

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

我们可以跳过对主页面的配置因为我们已经在博客Rails程序配置/英文完成了这个步骤。现在让我们来添加警告alerts的页面。我将不会把警告的页面添加到主页面当中,因为在有一些界面当中我们可能不想要实现警告的界面,或者说我们只想将警告的界面渲染到页面的特定位置。所以让我们在view目录下创建一个shared目录然后添加一个局部(partial)文件叫做_alerts.html.erb

<%#= app/views/shared/_alerts.html.erb %>

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

现在让我们简单的在application.html.erb文件中添加一个渲染的命令,我们将会在开始设计的时候将这个命令移除:

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

<%= render 'shared/alerts' %>

你发现了这种设计有多么干净吗?当我们在逐渐创建应用程序的过程当中,你将会发现我们会使用大量的局部(partial)文件来保持我们代码的干净和不重复(DRY)。现在让我们来使用以下的命令创建Devise的视图(view):

rails g devise:views

这段命令将会创建以下相关的视图(view)文件:

我很喜欢Devise生成器,然后它确实会创建一个我们并不需要的文件,现在让我们来删除掉那些我们不会使用的文件来避免程序显得很杂乱:

rm -rf app/views/devise/confirmations
rm -rf app/views/devise/mailer/confirmation_instructions.html.erb

现在让我们使用Devise生成器来创建User模型:

rails g devise User first_name:string last_name:string avatar:text username:string

这将会创建一个默认的User模型,我在这个模型的迁移(migration)文件当中插入了一些新的属性:first_name,last_name,avatarusername。现在让我们来运行命令rake db:migrate来在数据库中创建相应的表和schema.rb文件:

# db/schema.rb

create_table "users", force: :cascade do |t|
    t.string   "email",                  default: "", null: false
    t.string   "encrypted_password",     default: "", null: false
    t.string   "reset_password_token"
    t.datetime "reset_password_sent_at"
    t.datetime "remember_created_at"
    t.integer  "sign_in_count",          default: 0,  null: false
    t.datetime "current_sign_in_at"
    t.datetime "last_sign_in_at"
    t.inet     "current_sign_in_ip"
    t.inet     "last_sign_in_ip"
    t.string   "first_name"
    t.string   "last_name"
    t.text     "avatar"
    t.string   "username"
    t.datetime "created_at",                          null: false
    t.datetime "updated_at",                          null: false
end

add_index "users", ["email"], name: "index_users_on_email", unique: true, using: :btree
add_index "users", ["reset_password_token"], name: "index_users_on_reset_password_token", unique: true, using: :btree

以上的教程将会给我们生成足够的代码来让用户实现注册,登录和一些其他的标准的有关用户认证的操作。在下一个博客当中我们将会讲解如何自定义Devise

资源

代码

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