Я ненавижу подписываться на сайты. Я уже подписался на очень многих, используя разные имена пользователей, что вернуться к одному из них и попытаться запомнить мои учетные данные иногда невозможно. В наши дни большинство сайтов начали предлагать альтернативные способы регистрации, позволяя вам использовать свой Facebook, Twitter или даже учетную запись Google. Создание такой интеграции иногда кажется долгой и трудной задачей. Но не бойся, Омниавт здесь, чтобы помочь.
Omniauth позволяет легко интегрировать более шестидесяти провайдеров аутентификации, включая Facebook, Google, Twitter и GitHub. В этом руководстве я собираюсь объяснить, как интегрировать этих поставщиков аутентификации в ваше приложение.
Шаг 1: Подготовка вашего заявления
Давайте создадим новое приложение Rails и добавим необходимые гемы. Я предполагаю, что вы уже установили Ruby и Ruby on Rails 3.1, используя RubyGems.
1
|
rails new omniauth-tutorial
|
Теперь откройте свой Gemfile
и ссылайтесь на драгоценный камень omniauth.
1
|
gem ‘omniauth’
|
Затем, как обычно, выполните команду bundle install
чтобы установить гем.
Шаг 2: Создание провайдера
Чтобы добавить провайдера в Omniauth, вам необходимо зарегистрироваться в качестве разработчика на сайте провайдера. После того, как вы зарегистрируетесь, вы получите две строки (вроде имени пользователя и пароля), которые необходимо передать Omniauth. Если вы используете провайдера OpenID, то все, что вам нужно, это URL-адрес OpenID.
Если вы хотите использовать аутентификацию Facebook, зайдите на developers.facebook.com/apps и нажмите «Создать новое приложение».
Заполните всю необходимую информацию и после завершения скопируйте идентификатор своего приложения и секрет.
Настройка Twitter немного сложнее на компьютере разработчика, поскольку они не позволяют использовать «localhost» в качестве домена для обратных вызовов. Настройка среды разработки для такого рода целей выходит за рамки данного руководства, однако я рекомендую использовать Pow, если вы работаете на Mac.
Шаг 3: добавьте своих провайдеров в приложение
Создайте новый файл в config/initializers
под названием omniauth.rb
. Мы собираемся настроить наших провайдеров аутентификации через этот файл.
Вставьте следующий код в файл, который мы создали ранее:
1
2
3
|
Rails.application.config.middleware.use OmniAuth::Builder do
provider :facebook, YOUR_APP_ID, YOUR_APP_SECRET
end
|
Это, честно говоря, вся конфигурация, которая вам нужна для запуска. Об остальном позаботится Омниавт, как мы увидим на следующем шаге.
Шаг 4: Создание страницы входа
Давайте создадим наш контроллер сессий. Запустите следующий код в своем терминале, чтобы создать новый контроллер sessions
, а также new
, create
и действия при failure
.
1
|
rails generate controller sessions new create failure
|
Затем откройте файл config/routes.rb
и добавьте это:
1
2
3
|
get ‘/login’, :to => ‘sessions#new’, :as => :login
match ‘/auth/:provider/callback’, :to => ‘sessions#create’
match ‘/auth/failure’, :to => ‘sessions#failure’
|
Давайте разберем это:
- Первая строка используется для создания простой формы входа в систему, где пользователь увидит простую ссылку «Связаться с Facebook».
- Вторая строка — перехватить ответный звонок провайдера. После того как пользователь авторизует ваше приложение, провайдер перенаправляет пользователя на этот URL, чтобы мы могли использовать его данные.
- Последний будет использоваться, когда есть проблема, или если пользователь не авторизовал наше приложение.
Убедитесь, что вы удалили маршруты, которые были созданы автоматически при запуске команды rails generate
. Они не нужны для нашего маленького проекта.
Откройте файл app/controllers/sessions_controller.rb
и напишите метод create
следующим образом:
1
2
3
4
5
|
def create
auth_hash = request.env[‘omniauth.auth’]
render :text => auth_hash.inspect
end
|
Это используется, чтобы убедиться, что все работает. Укажите в браузере localhost: 3000 / auth / facebook, и вы будете перенаправлены на Facebook, чтобы авторизовать свое приложение (круто, а?). Авторизуйте его, и вы будете перенаправлены обратно в свое приложение и увидите хэш с некоторой информацией. Между ними будет ваше имя, ваш идентификатор пользователя Facebook и ваш адрес электронной почты, среди прочего.
Шаг 5: Создание пользовательской модели
Следующим шагом является создание модели пользователя, чтобы пользователи могли зарегистрироваться, используя свои учетные записи Facebook. В консоли Rails (консоль rails console
) создайте новую модель.
1
|
rails generate model User name:string email:string
|
На данный момент наша model
пользователя будет иметь только name
и email
. Для этого нам нужен способ распознавания пользователя при следующем входе в систему. Имейте в виду, что для этой цели у нас нет полей в модели нашего пользователя.
Идея, лежащая в основе приложения, подобного тому, которое мы пытаемся создать, заключается в том, что пользователь может выбирать между использованием Facebook или Twitter (или любого другого поставщика) для регистрации, поэтому нам нужна другая модель для хранения этой информации. Давайте создадим это:
1
|
rails generate model Authorization provider:string uid:string user_id:integer
|
У пользователя будет одна или несколько авторизаций, и когда кто-то пытается войти в систему с помощью провайдера, мы просто просматриваем авторизации в базе данных и ищем ту, которая соответствует полям uid
и provider
. Таким образом, мы также позволяем пользователям иметь много провайдеров, чтобы они могли позже войти в систему с помощью Facebook, Twitter или любого другого провайдера, которого они настроили!
Добавьте следующий код в файл app/models/user.rb
:
1
2
|
has_many :authorizations
validates :name, :email, :presence => true
|
Это указывает, что у user
может быть несколько полномочий, и что поля name
и email
в базе данных являются обязательными.
Далее, к вашему файлу app/models/authorization.rb
добавьте:
1
2
|
belongs_to :user
validates :provider, :uid, :presence => true
|
В рамках этой модели мы обозначаем, что каждая авторизация привязана к определенному user
. Мы также установили некоторые проверки.
Шаг 6: Добавление немного логики в наш контроллер сессий
Давайте добавим некоторый код в наш controller
сессий, чтобы он регистрировал пользователя или регистрировал его, в зависимости от случая. Откройте app/controllers/sessions_controller.rb
и измените метод create
следующим образом:
01
02
03
04
05
06
07
08
09
10
11
12
13
14
|
def create
auth_hash = request.env[‘omniauth.auth’]
@authorization = Authorization.find_by_provider_and_uid(auth_hash[«provider»], auth_hash[«uid»])
if @authorization
render :text => «Welcome back #{@authorization.user.name}! You have already signed up.»
else
user = User.new :name => auth_hash[«user_info»][«name»], :email => auth_hash[«user_info»][«email»]
user.authorizations.build :provider => auth_hash[«provider»], :uid => auth_hash[«uid»]
user.save
render :text => «Hi #{user.name}! You’ve signed up.»
end
end
|
Этот код явно нуждается в рефакторинге, но об этом мы поговорим позже. Давайте сначала рассмотрим это:
- Мы проверяем, существует ли авторизация для этого
provider
и этогоuid
. Если таковой существует, мы приветствуем нашего пользователя обратно. - Если авторизации не существует, мы регистрируем пользователя. Мы создаем нового пользователя с именем и адресом электронной почты, которые предоставляет нам провайдер (в данном случае Facebook), и связываем авторизацию с
provider
и предоставленным нам идентификатором.
Пройди тест! Перейдите на localhost: 3000 / auth / facebook, и вы должны увидеть «Вы зарегистрировались». Если вы обновите страницу, вы должны увидеть «Welcome back».
Шаг 7: Включение нескольких провайдеров
Идеальный сценарий — позволить пользователю зарегистрироваться с помощью одного поставщика, а затем добавить другого поставщика, чтобы у него было несколько вариантов входа в систему. Наше приложение пока не позволяет этого. Нам нужно немного реорганизовать наш код. Измените метод create
вашего sessions_controlller.rb
чтобы он выглядел следующим образом:
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
|
def create
auth_hash = request.env[‘omniauth.auth’]
if session[:user_id]
# Means our user is signed in. Add the authorization to the user
User.find(session[:user_id]).add_provider(auth_hash)
render :text => «You can now login using #{auth_hash[«provider»].capitalize} too!»
else
# Log him in or sign him up
auth = Authorization.find_or_create(auth_hash)
# Create the session
session[:user_id] = auth.user.id
render :text => «Welcome #{auth.user.name}!»
end
end
|
Давайте рассмотрим это:
- Если пользователь уже вошел в систему, мы добавим поставщика, которого они используют, в свою учетную запись.
- Если они не вошли в систему, мы попытаемся найти пользователя с этим провайдером или создать нового, если это необходимо.
Чтобы приведенный выше код работал, нам нужно добавить несколько методов в наши модели User
и Authorization
. Откройте user.rb
и добавьте следующий метод:
1
2
3
4
5
6
|
def add_provider(auth_hash)
# Check if the provider already exists, so we don’t add it twice
unless authorizations.find_by_provider_and_uid(auth_hash[«provider»], auth_hash[«uid»])
Authorization.create :user => self, :provider => auth_hash[«provider»], :uid => auth_hash[«uid»]
end
end
|
Если у пользователя еще нет этого провайдера, связанного с его учетной записью, мы добавим его — просто. Теперь добавьте этот метод в ваш файл authorization.rb
:
1
2
3
4
5
6
7
8
|
def self.find_or_create(auth_hash)
unless auth = find_by_provider_and_uid(auth_hash[«provider»], auth_hash[«uid»])
user = User.create :name => auth_hash[«user_info»][«name»], :email => auth_hash[«user_info»][«email»]
auth = create :user => user, :provider => auth_hash[«provider»], :uid => auth_hash[«uid»]
end
auth
end
|
В приведенном выше коде мы пытаемся найти авторизацию, соответствующую запросу, и в случае неудачи мы создаем нового пользователя.
Если вы хотите попробовать это локально, вам понадобится второй поставщик аутентификации. Вы можете использовать OAuth-систему Twitter, но, как я уже говорил ранее, вам нужно будет использовать другой подход, поскольку Twitter не позволяет использовать «localhost» в качестве домена URL-адреса обратного вызова (по крайней мере, он не работает для меня). Вы также можете попробовать разместить свой код на Heroku , который идеально подходит для простого сайта, такого как тот, который мы создаем.
Шаг 8: некоторые дополнительные настройки
Наконец, мы должны, конечно, разрешить пользователям выходить из системы. Добавьте этот кусок кода в ваш контроллер сессий:
1
2
3
4
|
def destroy
session[:user_id] = nil
render :text => «You’ve logged out!»
end
|
Нам также нужно создать подходящий маршрут (в routes.rb
).
1
|
get ‘/logout’, :to => ‘sessions#destroy’
|
Это так просто! Если вы перейдете к localhost: 3000 / logout , ваш сеанс должен быть очищен, и вы выйдете из системы. Это облегчит использование нескольких учетных записей и поставщиков. Нам также нужно добавить сообщение, которое отображается, когда пользователи отказывают в доступе к нашему приложению. Если вы помните, мы добавили этот маршрут в начале урока. Теперь нам нужно только добавить метод в контроллер sessions
:
1
2
3
|
def failure
render :text => «Sorry, but you didn’t allow access to our app!»
end
|
И, наконец, что не менее важно, создайте страницу входа, где пользователь может щелкнуть ссылку «Подключиться к Facebook». Откройте app/views/sessions/new.html.erb
и добавьте:
1
|
<%= link_to «Connect With Facebook», «/auth/facebook» %>
|
Если вы перейдете на localhost: 3000 / login, вы увидите ссылку, которая перенаправит вас на страницу аутентификации Facebook.
Вывод
Я надеюсь, что эта статья предоставила вам краткий пример того, как работает Omniauth. Это очень мощная жемчужина, которая позволяет создавать веб-сайты, которые не требуют регистрации пользователей, что всегда является плюсом! Вы можете узнать об Omniauth на GitHub .
Дайте нам знать, если у вас есть какие-либо вопросы!