如何为 Rails 应用程序配置 Devise 和 OmniAuth

介绍

大多数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 地址)。

Sign In page

您可以注册为新用户,访问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的登录页面. 成功登录后,您将被重定向回自己的应用程序,并显示产品页面。

Sign in with DigitalOcean

结论

您现在为您的应用程序拥有现代的用户身份验证系统,用户可以使用电子邮件地址,社交网络帐户或其他流行的服务登录。

如果你决定在Droplet上生产这个应用程序,你可以参考这里的教程: 如何使用DigitalOcean One Click Image启动你的Ruby on Rails应用程序

Published At
Categories with 技术
comments powered by Disqus