вівторок, 21 лютого 2012 р.

OmniAuth Identity з DataMapper в Sinatra

З виходом OmniAuth версії 1.0 з'явилася нова стратегія Identity, яка дозволяє використовувати традиційну аутентифікацію по логіну і паролю.

Раніше я вже писав про OmniAuth - раз і два.

У цій статті ми познайомимося з стратегією під назвою Identity, яка дозволяє користувачу створити обліковий запис, вказавши ім'я користувача та пароль, замість входу через зовнішнього постачальника.

Вихідний код цієї статті заснований на OmniAuth для Sinatra, і якщо ви не знайомі з OmniAuth цю статтю варто прочитати в першу чергу.

omniauth-identity підключається, як і будь-яка інша стратегія OmniAuth. Основні настройки для логіна/пароля матимуть наступний вигляд:
use OmniAuth::Builder do
  provider :identity, :fields => [:email, :name]
end

Далі необхідно створити модель, яка буде зберігати інформацію, надану користувачем. За замовчуванням ця модель матиме назву Identity, але ми можемо налаштувати цей параметр, якщо потрібно. Ми повинні дати їй поля name , email та password_digest.

В README описані приклади моделей для роботи з різними ORM. На жаль, готової моделі для DataMapper немає. Але маючи повний доступ до вихідного коду, написати її не складає проблеми. Не вдаючись в подробиці, ось мій Pull Request, що додає підтримку DataMapper у omniauth-identity.

Створюємо модель успадковану від OmniAuth::Identity::Models::DataMapper:
class Identity
  include DataMapper::Resource
  include OmniAuth::Identity::Models::DataMapper

  property :id,              Serial
  property :email,           String
  property :name,            String
  property :password_digest, Text

  attr_accessor :password_confirmation

  validates_uniqueness_of :email
  validates_presence_of :name
end

Визначаємо модель Account з попередньої статті для збереження інформації про всіх користувачів у базі даних:
class Account
  include DataMapper::Resource

  property :id,         Serial
  property :uid,        String
  property :name,       String
  property :email,      String
  property :provider,   String
  property :image,      String
  property :created_at, DateTime
end

Ми майже закінчили. Тепер можна направляти користувачів на /auth/identity, де буде запит входу в систему або можливість створити новий аккаунт.
Після успішної аутентифікації, OmniAuth перенаправляє до /auth/identity/callback, де створюємо у таблиці accounts нового користувача з заданими полями, або використовуємо вже існуючого. І додаємо інформацію про користувача у сесію для подальшого використання.
post '/auth/identity/callback' do
  auth = request.env['omniauth.auth']

  user = Account.first_or_create({ :provider => auth['provider'], :uid => auth['uid'] }, {
    :uid      => auth['uid'],
    :name     => auth['info']['name'],
    :provider => auth['provider'],
    :email    => auth['info']['email']
  })

  session[:user_id] = user.id
  redirect '/'
end

Ресурси:

Немає коментарів: