Система аутентифікації і контролю доступу Padrino забезпечує простий спосіб створювати свої системи аутентифікації. У поєднанні з OmniAuth ви можете легко використовувати її для аутентифікації за допомогою різних методів. Читайте нижче для більш докладної інформації про те, як інтегрувати їх.
У цій статті ми розглянемо дві теми:
- Інтеграцію Padrino Admin Authentication в усі додатки вашого проекту
- Створення власних стратегій аутентифікації
На відміну від оригінальної статті, де у якості ORM використовується ActiveRecord, тут ми будемо використовувати DataMapper, про який я писав тут. Можливо вам необхідно познайомитись з фреймворком Padrino, про який я писав тут і тут. І про OmniAuth тут.
Перш ніж ми почнемо, важливо відзначити, що наша вбудована аутентифікація, що базується на ролях, може взаємодіяти з іншими системами. Потрібно лише внести зміни у файли session.rb і account.rb для того щоб додати свій власний код.
Отже, давайте почнемо зі створення проекту використовуючи DataMapper:
$ padrino g project omniauth_dm --orm datamapper --tiny
$ cd omniauth_dm/
$ bundle install
Додаємо модель Account:
$ padrino g model Account name:string email:string role:string uid:string provider:string
name | ім'я користувача |
---|---|
email користувача | |
role | роль контролю доступу |
uid | ідентифікатор користувача omniauth |
provider | постачальник omniauth |
Створюємо базу даних:
$ padrino rake dm:migrate
Відкриваємо файл Gemfile і додаємо рядок:
# Gemfile
gem 'omniauth'
Запускаємо bundle install щоб встановити залежності:
$ bundle install
Тепер потрібно додати OmniAuth middleware. Тут доступні два шляхи:
- Додати middleware для всьо проекту(таким чином всі піддодатки зможуть використовувати його)
- Додати middleware тільки для додатку, який його потребує
В нашому прикладі, нам потрібно просто змінити app/app.rb:
# app/app.rb
class OmniauthDm < Padrino::Application
# ...
use OmniAuth::Builder do
provider :vkontakte, 'application_id', 'secure_key'
provider :facebook, 'app_id', 'app_secret'
end
# ...
end
Якщо ви вибрали multiapp сценарій вам необхідно відредагувати config/boot.rb:
# config/boot.rb
Padrino.use OmniAuth::Builder do
provider :vkontakte, 'application_id', 'secure_key'
provider :facebook, 'app_id', 'app_secret'
end
# before the line
Padrino.load!
Для отримання app_id і app_secret для Facebook необхідно:
- Перейти до сторінки розробників Facebook
- Натиснути Створити новий додаток
- Вказати ім’я додатку і заповнити форму
- Закінчивши, ви зможете змінити налаштування. Перейдіть у розділ Website
- Додати до site url: http://localhost:3000
- Додати до domain: localhost
- Записати "Application ID" і "Application Secret" до OmniAuth::Builder
Для отримання application_id і secure_key для ВКонтакте необхідно:
- Перейти до сторінки для розробників ВКонтакте
- Натиснути Створити додаток
- Вказати ім’я додатку і заповнити форму
- Закінчивши, ви зможете змінити налаштування.
- Додати до "Адреса сайту": http://localhost:3000/
- Додати до "Базовий домен": localhost
- Записати "ID додатку" і "Захисний ключ" до OmniAuth::Builder
ПРИМІТКА: Для домену не важливо чи шлях існуючий, тому що OmniAuth змінює callback url.
Далі, ми можемо інтегрувати нашу системи аутентифікації у app/app.rb:
class OmniauthDm < Padrino::Application
# ...
register Padrino::Admin::AccessControl
set :login_page, "/" # визначає URL для входу
access_control.roles_for :any do |role|
role.protect "/profile"
role.protect "/admin"
end
# тепер додаємо роль для користувачів
access_control.roles_for :users do |role|
role.allow "/profile"
end
# ...
end
І додамо декілька маршрутів у app/controllers.rb:
OmniauthDm.controllers do
# ...
get :index do
haml <<-HAML.gsub(/^ {6}/, '')
- if !current_account.nil?
Hello
=link_to(current_account['name'], url(:profile))
%br
=button_to('Log Out', url(:destroy), :method => :delete)
- else
Login with
=link_to('Facebook', '/auth/facebook')
or
=link_to('Vk', '/auth/vkontakte')
HAML
end
get :profile do
content_type :text
current_account.to_yaml
end
delete :destroy do
set_current_account(nil)
redirect url(:index)
end
get :auth, :map => '/auth/:provider/callback' do
auth = request.env["omniauth.auth"]
account = Account.find_by_provider_and_uid(auth["provider"], auth["uid"]) ||
Account.create_with_omniauth(auth)
set_current_account(account)
redirect "http://" + request.env["HTTP_HOST"] + url(:profile)
end
# ...
end
Вище ми посилаємося до методу Account.create_with_omniauth. Крім того для забезпечення працездатності потрібно створити методи find_by_id та find_by_provider_and_uid, які в ActiveRecord визначаються автоматично завдяки так званим "Dynamic attribute-based finders". Відкрийте app/models/account.rb і додате:
class Account
# ...
def self.find_by_id(id)
get(id) rescue nil
end
def self.find_by_provider_and_uid(provider, uid)
first(:provider => provider, :uid=> uid) rescue nil
end
def self.create_with_omniauth(auth)
account = Account.new
account.provider = auth["provider"]
account.uid = auth["uid"]
account.name = auth["user_info"]["name"] if auth["user_info"]
account.email = auth["user_info"]["email"] if auth["user_info"] # тільки для Facebook. ВКонтакте не повертає email користувача :(
account.role = "users"
account.save
return account
end
# ...
end
Настрав час запустити сервер і подивитись, що у нас вийшло:
$ padrino start
Перейдіть до http://localhost:3000/profile
Це приведе вас до початкової сторінки login_page, в нашому випадку /.
Тепер ви можете увійти тут http://localhost:3000
Це все, що вам потрібно для налаштувати скелету системи аутентифікації в Padrino.
Немає коментарів:
Дописати коментар