Как настроить Devise и OmniAuth для вашего приложения Rails
Введение
Для большинства приложений Ruby on Rails требуются механизмы регистрации и аутентификации пользователей. Их разработка с нуля требует много времени и усилий — к счастью, есть Devise. Используя гем Devise, вы можете настроить полноценную систему аутентификации пользователей за считанные минуты.
Однако вы можете сделать своих пользователей более счастливыми, разрешив им доступ к вашему приложению без создания новой учетной записи. Они могли просто войти в систему, используя свои существующие учетные записи Facebook, Twitter, Amazon или DigitalOcean. На самом деле вы можете поддерживать аутентификацию с помощью любого популярного поставщика услуг OAuth. Поддержка OAuth обеспечивается гемом OmniAuth. В этом руководстве мы создадим простое приложение, использующее Devise и OmniAuth.
Предпосылки
Прежде чем начать, убедитесь, что на вашем хосте установлены последние версии RVM, Ruby и Rails. Если нет, следуйте инструкциям здесь: Как установить Ruby on Rails на Ubuntu 12.04 LTS с RVM.
Это руководство было протестировано с Ruby 2.1.2 и Rails 4.1.5.
Шаг 1 — Создайте новое приложение Rails
Рекомендуется, чтобы все ваши приложения Rails находились в отдельном каталоге.
Вы должны создать его сейчас.
mkdir rails_apps
cd rails_apps
Вы должны инициализировать среду RVM, прежде чем начнете выполнять команды Rails.
Если вы сделаете перерыв, следуя этому руководству, не забывайте делать это каждый раз при перезапуске сеанса терминала.
. ~/.rvm/scripts/rvm
rvm use ruby --default
Давайте назовем новое приложение myapp. После создания приложения используйте cd, чтобы войти в базовый каталог приложения.
rails new myapp
cd myapp
Примечание. Все команды Rails следует запускать из каталога вашего приложения, в данном случае ~/rails_apps/myapp.
Шаг 2 — Добавьте необходимые драгоценные камни в Gemfile
Нам понадобятся драгоценные камни Devise и OmniAuth. Кроме того, вам также понадобится отдельный гем для каждого поставщика услуг OAuth, которого вы хотите поддерживать. В этом руководстве мы будем поддерживать вход с помощью DigitalOcean, поэтому нам понадобится гем omniauth-digitalocean.
Добавьте следующие строки в конец файла ~/rails_apps/myapp/Gemfile
. Вы можете использовать nano в качестве текстового редактора.
gem 'therubyracer'
gem 'devise'
gem 'omniauth'
gem 'omniauth-digitalocean'
Вам понадобятся аналогичные драгоценные камни для поддержки других поставщиков. Например, для поддержки Facebook вам понадобится omniauth-facebook. Вот некоторые из таких драгоценных камней для справки:
- Twitter — omniauth-twitter
- Amazon — omniauth-amazon
- Google – omniauth-google
- Github — omniauth-github
Установите недавно добавленные драгоценные камни.
bundle install
Шаг 3. Добавьте базовую функциональность в приложение
Давайте быстро добавим несколько страниц в это приложение для тестирования. В конечном итоге эти страницы будут доступны только после входа в систему.
Для этого мы можем использовать скаффолдинг в Rails. Используя команду rails g scaffold, мы просто указываем подробности о модели, и Rails генерирует полнофункциональные страницы для выполнения операций CRUD (Create Read Update Delete) над этой моделью. Другими словами, все связанные контроллеры и представления генерируются вместе с файлом модели.
rails g scaffold Product name:string price:integer description:text
rake db:migrate
Далее мы должны определить корень этого приложения.
Отредактируйте ~/rails_apps/myapp/config/routes.rb
и добавьте строку root products#index
, чтобы указать корень приложения, чуть ниже существующего ресурсы строка. Вы можете игнорировать все закомментированные строки. Когда вы закончите, активные строки в файле будут выглядеть так:
Rails.application.routes.draw do
resources :products
root 'products#index'
end
Давай, протестируй свое приложение прямо сейчас. Запустите сервер разработки, введя:
rails s
Посетите http://localhost:3000/ в своем браузере. Если вы разрабатываете удаленно, замените localhost на соответствующий IP-адрес или домен для вашей капли. 3000 — это номер порта по умолчанию для сервера разработки.
На данный момент вход в систему не требуется. Добавьте пару продуктов, нажав «Новый продукт». Когда вы убедитесь, что ваше приложение работает должным образом, вернитесь к терминалу и нажмите Ctrl+C, чтобы остановить сервер.
Шаг 4 - Настройте устройство
Введите следующие команды, чтобы добавить поддержку аутентификации Devise.
rails generate devise:install
rails generate devise User
rake db:migrate
Это добавляет формы входа и регистрации, а также всю связанную с ними логику.
В нашем приложении теперь есть базовая система аутентификации, в которой пользователи могут зарегистрироваться, а затем войти в систему. Однако все страницы по-прежнему доступны напрямую. Чтобы изменить это, отредактируйте ~/rails_apps/myapp/app/controllers/application_controller.rb
и добавьте authenticate_user! в качестве действия, которое необходимо выполнить перед обслуживанием любой страницы.
class ApplicationController < ActionController::Base
protect_from_forgery with: :exception
before_action :authenticate_user!
end
При желании вы можете снова запустить сервер разработки с помощью команды rails s и проверить эти недавно добавленные страницы, посетив http://localhost: 3000/
(опять же, используйте свой собственный домен или IP-адрес). Вы должны увидеть страницу, которая выглядит следующим образом:
Вы можете зарегистрироваться как новый пользователь, посетив http://localhost:3000/users/sign_up
.
Шаг 5. Обновите модель пользователя для поддержки OmniAuth
Если вы снова запустили сервер, остановите его, нажав CTRL-C. Добавьте новый столбец с именем uid в модель, созданную Devise.
rails g migration AddColumnsToUsers provider uid
rake db:migrate
Шаг 6. Получите идентификатор клиента и секрет клиента от поставщика услуг OAuth.
Посетите веб-сайт поставщика услуг и зарегистрируйте свое приложение там. У всех поставщиков услуг разные процедуры регистрации. Для DigitalOcean обратитесь к руководству здесь: Как использовать аутентификацию OAuth с DigitalOcean в качестве пользователя или разработчика
Вам будет предложено ввести URL-адрес обратного вызова в процессе регистрации. Для каждого поставщика существует отдельный URL-адрес обратного вызова. Вот URL-адреса обратного вызова для нескольких популярных поставщиков услуг:
- Digital Ocean: http://localhost:3000/users/auth/digitalocean/callback
- Facebook: http://localhost:3000/users/auth/facebook/callback
- Amazon: http://localhost:3000/users/auth/amazon/callback
- Твиттер: http://localhost:3000/users/auth/twitter/callback
- Google: http://localhost:3000/users/auth/google/callback
Пожалуйста, замените localhost на IP-адрес или домен, который разрешается в вашу каплю. В конце процесса регистрации вам будет предоставлен ваш идентификатор клиента и секрет клиента. Вы будете использовать эти значения на следующем шаге.
Шаг 7 — Обновите инициализатор Devise
Отредактируйте ~/rails_apps/myapp/config/initializers/devise.rb
, чтобы добавить идентификаторы клиентов и секреты в конец файла, непосредственно перед строкой end
. Также рекомендуется обновить mailer_sender на что-то, что имеет имя вашего сервера и пользователя. Вам не нужно вносить никаких других изменений, кроме этих двух пунктов.
После редактирования ваш файл будет выглядеть так (также в файле будет много закомментированных строк):
Devise.setup do |config|
#Replace example.com with your own domain name
config.mailer_sender = 'mailer@example.com'
require 'devise/orm/active_record'
config.case_insensitive_keys = [ :email ]
config.strip_whitespace_keys = [ :email ]
config.skip_session_storage = [:http_auth]
config.stretches = Rails.env.test? ? 1 : 10
config.reconfirmable = true
config.expire_all_remember_me_on_sign_out = true
config.password_length = 8..128
config.reset_password_within = 6.hours
config.sign_out_via = :delete
#Add your ID and secret here
#ID first, secret second
config.omniauth :digitalocean, "db381dc9990be7e3bc42503d0", "5b0824c2722b65d29965f1a1df"
end
Шаг 8 — Обновите модель пользователя
Модель пользователя, созданную Devise, необходимо изменить, чтобы указать поставщиков услуг, которых мы хотим использовать. Мы добавляем три элемента в существующий список (:omniauthable, :omniauth_providers => [:digitalocean], и не забудьте лишнюю запятую!). Мы также создаем новый метод с именем from_omniauth для извлечения информации, доступной после аутентификации.
После редактирования ваш ~/rails_apps/myapp/app/models/user.rb
должен выглядеть так:
class User < ActiveRecord::Base
devise :database_authenticatable, :registerable,
:recoverable, :rememberable, :trackable, :validatable,
:omniauthable, :omniauth_providers => [:digitalocean]
def self.from_omniauth(auth)
where(provider: auth.provider, uid: auth.uid).first_or_create do |user|
user.provider = auth.provider
user.uid = auth.uid
user.email = auth.info.email
user.password = Devise.friendly_token[0,20]
end
end
end
Сохраните файл.
Шаг 9. Добавьте контроллер для обработки URL-адресов обратного вызова
Сначала отредактируйте ~/rails_apps/myapp/config/routes.rb
и обновите строку devise_for, указав имя контроллера, который будет обрабатывать обратные вызовы. Давайте просто назовем это обратными вызовами. Теперь ваш файл должен выглядеть так (за вычетом закомментированных разделов):
Rails.application.routes.draw do
devise_for :users, :controllers => { :omniauth_callbacks => "callbacks" }
resources :products
root 'products#index'
end
Затем создайте новый файл ~/rails_apps/myapp/app/controllers/callbacks_controller.rb
.
Добавьте в него следующий код:
class CallbacksController < Devise::OmniauthCallbacksController
def digitalocean
@user = User.from_omniauth(request.env["omniauth.auth"])
sign_in_and_redirect @user
end
end
Если вы использовали больше провайдеров OAuth, вам понадобится отдельный метод для каждого из них. Имя метода должно совпадать с именем провайдера. Например, чтобы добавить поддержку Facebook, ваш метод будет определен с помощью def facebook.
Ваше приложение готово. Запустите ваш сервер снова:
rails s
Посетите свою домашнюю страницу. Поскольку мы тестируем функцию входа в систему, вы можете сделать это в сеансе без сохраненных данных, например в окне Chrome в режиме инкогнито. Вы должны увидеть ссылку Войти с помощью Digitalocean. Нажмите здесь. Вы должны быть перенаправлены на страницу входа в DigitalOcean. После успешного входа в систему вы будете перенаправлены обратно в собственное приложение, и будет показана страница продуктов.
Заключение
Теперь у вас есть современная система аутентификации пользователей для вашего приложения, где пользователи могут входить в систему, используя адрес электронной почты, учетную запись в социальной сети или другую популярную службу.
Если вы когда-нибудь решите запустить это приложение в производство на дроплете, вы можете обратиться к руководству здесь: Как запустить приложение Ruby on Rails с изображением DigitalOcean One Click. Если вы добавите свое приложение в новый дроплет, не забудьте вернуться к шагу 6, чтобы обновить настройки API DigitalOcean с помощью URL-адресов обратного вызова вашего рабочего сервера.