介绍
大多数Ruby on Rails应用程序都需要用户注册和身份验证机制,从头开始开发需要大量的时间和精力 - 幸运的是,有 Devise 。
然而,你可以让你的用户更开心,允许他们访问你的应用程序而不创建一个新的帐户。他们可以简单地使用他们现有的Facebook,Twitter,Amazon或DigitalOcean帐户登录。事实上,你可以支持任何受欢迎的OAuth服务提供商的身份验证。OAuth支持由OmniAuth宝石提供。
前提条件
在您开始之前,请确保您在您的主机上安装了最新版本的 RVM、Ruby 和 Rails。如果您没有,请遵循以下说明: 如何在 Ubuntu 12.04 LTS 上安装 Ruby on Rails 使用 RVM
本教程已通过 Ruby 2.1.2 和 Rails 4.1.5 进行测试。
步骤1 - 创建一个新的 Rails 应用程序
建议您将所有 Rails 应用程序放在一个单独的目录中。
你现在应该创建一个。
1mkdir rails_apps
2cd rails_apps
您必须在开始发出 Rails 命令之前初始化 RVM 环境。
如果您在遵循本教程时休息,请记住每次重新启动终端会话时要这样做。
1. ~/.rvm/scripts/rvm
2rvm use ruby --default
让我们将新应用程序称为 myapp . 创建应用程序后,使用 cd 进入应用程序的基本目录。
1rails new myapp
2cd myapp
**注意:所有 Rails 命令应从应用程序目录中运行,在这种情况下是 ~/rails_apps/myapp。
步骤 2 - 添加必要的宝石到宝藏
我们需要 Devise 和 OmniAuth 宝石,此外,您还需要为您想要支持的每个 OAuth 服务提供商提供一个单独的宝石。
将下列行添加到文件的末尾 ~/rails_apps/myapp/Gemfile
. 你可以使用 nano 作为你的文本编辑器。
1gem 'therubyracer'
2gem 'devise'
3gem 'omniauth'
4gem 'omniauth-digitalocean'
您将需要类似的宝石来支持其他提供商,例如,要支持Facebook,您将需要omniauth-facebook。
- Twitter - omniauth-twitter * 亚马逊 - omniauth-amazon * Google - omniauth-google * Github - omniauth-github
安装新增的宝石。
1bundle install
步骤3 - 向应用程序添加基本功能
让我们快速添加几页到这个应用程序进行测试,最终这些页面只在登录后才可访问。
使用 rails g scaffold 命令,我们简单地指定模型的细节,Rails 会生成功能齐全的页面,在该模型上执行 CRUD (Create Read Update Delete) 操作。
1rails g scaffold Product name:string price:integer description:text
2rake db:migrate
接下来,我们必须定义这个应用的根源。
编辑 ~/rails_apps/myapp/config/routes.rb
,并添加行 `root 'products# index'' 以指定应用程序的根,就在现有资源行下面。
1Rails.application.routes.draw do
2 resources :products
3 root 'products#index'
4end
继续,现在测试您的应用程序. 通过键入开始开发服务器:
1rails s
请从您的浏览器访问 http://localhost:3000/ 如果您正在远程开发,请用适当的 IP 地址或域名替换 localhost 。
目前,无需登录. 通过点击新产品
添加几个产品. 一旦您确信您的应用程序按预期运行,请返回终端并按 Ctrl+C 来停止服务器。
步骤4 - 设置命令
输入以下命令以添加 Devise 身份验证支持。
1rails generate devise:install
2rails generate devise User
3rake db:migrate
这增加了登录和登录表单,以及所有相关的逻辑。
我们的应用程序现在有一个基本的身份验证系统,用户可以注册自己,然后登录。然而,所有页面仍然可以直接访问。 要更改这一点,请编辑 ~/rails_apps/myapp/app/controllers/application_controller.rb
并添加 authenticate_user! 作为在服务任何页面之前必须执行的操作。
1class ApplicationController < ActionController::Base
2 protect_from_forgery with: :exception
3 before_action :authenticate_user!
4end
如果你愿意,你可以用 rails s 命令重新启动开发服务器,并通过访问 http://localhost:3000/
查看这些新添加的页面(再次使用自己的域名或 IP 地址)。
您可以注册为新用户,访问http://localhost:3000/users/sign_up`。
步骤5 - 更新用户模型以支持OmniAuth
如果您重新启动服务器,请使用 CTRL-C 停止使用它. 将一个名为 uid 的新列添加到 Devise 生成的模型中。
1rails g migration AddColumnsToUsers provider uid
2rake db:migrate
步骤 6 - 从 OAuth 服务提供商获取客户 ID 和客户机密
请访问服务提供商的网站并在那里注册您的应用程序. 所有服务提供商都有不同的注册程序. 对于 DigitalOcean,请参阅本教程: 如何使用 DigitalOcean 作为用户或开发人员使用 OAuth 身份验证
在注册过程中,您将被要求提供回调 URL. 每个服务提供商都有一个单独的回调 URL. 以下是几个流行的服务提供商的回调 URL:
- 数字海洋: http://localhost:3000/users/auth/digitalocean/callback * Facebook: http://localhost:3000/users/auth/facebook/callback * 亚马逊: http://localhost:3000/users/auth/amazon/callback * 推特: http://localhost:3000/users/auth/twitter/callback * 谷歌: http://localhost:3000/users/auth/google/callback
请用 IP 地址或域名代替 localhost 以解决您的 Droplet 问题。在注册过程结束时,您将获得客户端 ID 和客户端秘密。
第7步:更新 Devise Initializer
编辑~/rails_apps/myapp/config/initializers/devise.rb
以在文件底部添加客户端ID和秘密,就在end
行之前。
编辑后,您的文件将看起来像这样(文件中也将有许多评论的行):
1Devise.setup do |config|
2 #Replace example.com with your own domain name
3 config.mailer_sender = '[email protected]'
4
5 require 'devise/orm/active_record'
6 config.case_insensitive_keys = [ :email ]
7 config.strip_whitespace_keys = [ :email ]
8 config.skip_session_storage = [:http_auth]
9 config.stretches = Rails.env.test? ? 1 : 10
10 config.reconfirmable = true
11 config.expire_all_remember_me_on_sign_out = true
12 config.password_length = 8..128
13 config.reset_password_within = 6.hours
14 config.sign_out_via = :delete
15
16 #Add your ID and secret here
17 #ID first, secret second
18 config.omniauth :digitalocean, "db381dc9990be7e3bc42503d0", "5b0824c2722b65d29965f1a1df"
19end
第8步:更新用户模型
我们正在将三个项目添加到现有的列表中(:omniauthable, :omniauth_providers => [:digitalocean] ,不要忘记额外的句子!).我们还创建了一个名为_omniauth的新方法来提取身份验证后可用的信息。
编辑后,您的 ~/rails_apps/myapp/app/models/user.rb
应该是这样的:
1class User < ActiveRecord::Base
2 devise :database_authenticatable, :registerable,
3 :recoverable, :rememberable, :trackable, :validatable,
4 :omniauthable, :omniauth_providers => [:digitalocean]
5
6 def self.from_omniauth(auth)
7 where(provider: auth.provider, uid: auth.uid).first_or_create do |user|
8 user.provider = auth.provider
9 user.uid = auth.uid
10 user.email = auth.info.email
11 user.password = Devise.friendly_token[0,20]
12 end
13 end
14end
保存檔案
步骤9 - 添加控制器来处理回调 URL
首先,编辑 ~/rails_apps/myapp/config/routes.rb
并更新 devise_for 行,以指定将处理回调的控制器的名称。
1Rails.application.routes.draw do
2 devise_for :users, :controllers => { :omniauth_callbacks => "callbacks" }
3 resources :products
4 root 'products#index'
5end
然后,创建一个新的文件 ~/rails_apps/myapp/app/controllers/callbacks_controller.rb
。
添加以下代码:
1class CallbacksController < Devise::OmniauthCallbacksController
2 def digitalocean
3 @user = User.from_omniauth(request.env["omniauth.auth"])
4 sign_in_and_redirect @user
5 end
6end
如果您已经使用了多个OAuth提供商,您将需要为每个提供商提供一个单独的方法,该方法的名称应与提供商的名称匹配,例如,要添加对Facebook的支持,您的方法将使用def facebook定义。
您的应用程序已经准备好了. 再次点燃您的服务器:
1rails s
访问您的主页. 由于我们正在测试登录功能,您可能希望在没有存储数据的会话中这样做,例如Chrome Incognito窗口. 您应该看到一个 登录与 Digitalocean 链接. 点击它。 您应该被重定向到DigitalOcean的登录页面. 成功登录后,您将被重定向回自己的应用程序,并显示产品页面。
结论
您现在为您的应用程序拥有现代的用户身份验证系统,用户可以使用电子邮件地址,社交网络帐户或其他流行的服务登录。
如果你决定在Droplet上生产这个应用程序,你可以参考这里的教程: 如何使用DigitalOcean One Click Image启动你的Ruby on Rails应用程序。