Я пытаюсь реализовать аутентификацию от Facebook в своем приложении для модели клиента. Я уже выполнил аутентификацию для клиентов с помощью Devise. Я следовал this guide. В инициализаторе devise.rb я добавил эту строку:Rails 4 Проверка подлинности Facebook с помощью Devise и Omniauth
config.omniauth :facebook, ENV['FACEBOOK_KEY'], ENV['FACEBOOK_SECRET'], scope: "email"
Это моя модель клиента:
class Customer < ActiveRecord::Base
# Include default devise modules. Others available are:
# :confirmable, :lockable, :timeoutable and :omniauthable
devise :database_authenticatable, :registerable, :omniauthable,
:recoverable, :rememberable, :trackable #, :validatable
validates_presence_of :name
validates_uniqueness_of :nickname
before_save :complete_nickname
def complete_nickname
if !self.nickname?
self.nickname = self.email
end
end
def facebook
identities.where(:provider => "facebook").first
end
def facebook_client
@facebook_client ||= Facebook.client(access_token: facebook.accesstoken)
end
end
Это моя модель идентичности, написанном, как указано в руководстве:
class Identity < ActiveRecord::Base
belongs_to :customer
validates_presence_of :uid, :provider
validates_uniqueness_of :uid, :scope => :provider
def self.find_for_oauth(auth)
identity = find_by(provider: auth.provider, uid: auth.uid)
identity = create(uid: auth.uid, provider: auth.provider) if identity.nil?
identity.accesstoken = auth.credentials.token
identity.refreshtoken = auth.credentials.refresh_token
identity.name = auth.info.name
identity.email = auth.info.email
identity.nickname = auth.info.name.gsub(/\s+/, "")
identity.image = auth.info.image
identity.phone = auth.info.phone
identity.urls = (auth.info.urls || "").to_json
identity.save
identity
end
end
Это мой OmniauthCallbackController
class OmniauthCallbacksController < Devise::OmniauthCallbacksController
def facebook
generic_callback('facebook')
end
def generic_callback(provider)
@identity = Identity.find_for_oauth env["omniauth.auth"]
@customer = @identity.customer || current_customer
if @customer.nil?
@customer = Customer.create(email: @identity.email || "", nickname: @identity.email || "")
@identity.update_attribute(:customer_id, @customer.id)
end
if @customer.email.blank? && @identity.email
@customer.update_attribute(:email, @identity.email)
end
if @customer.persisted?
@identity.update_attribute(:customer_id, @customer.id)
# This is because we've created the user manually, and Device expects a
# FormUser class (with the validations)
@customer = FormUser.find @customer.id
sign_in_and_redirect @customer, event: :authentication
set_flash_message(:notice, :success, kind: provider.capitalize) if is_navigational_format?
else
session["devise.#{provider}_data"] = env["omniauth.auth"]
redirect_to new_customer_registration_url
end
end
end
Когда я нажимаю «Войти в систему с помощью Facebook», я не аутентифицирован, и приложение перенаправляет меня на форму входа. На сервере outuput я вижу, что он пытался создать клиент, но это не удается, и откаты:
SQL (0.3ms) UPDATE "identities" SET "accesstoken" = $1, "updated_at" = $2 WHERE "identities"."id" = $3 [["accesstoken", "CAABtFtDqAlwBAEFzpAtw2W2gUTLkpKbtjI4lqKibkIO5kyJSwNYK9TDzDG4NfEoq40oQdUzXxZADRZBwYy319KPobEU6378ULwQ3PtKT46EbEugs4eIdsQyfZC3S8yLIJoPW6uq7ZAF0AnEeepDvl97ajbazsmGsuP22rnK0G1zSTHzoBfPpGZAD4NkgW7Kp5r5TiLhxxEgZDZD"], ["updated_at", "2015-11-24 11:18:28.010402"], ["id", 2]]
(65.7ms) COMMIT
(0.2ms) BEGIN
Customer Exists (4.0ms) SELECT 1 AS one FROM "customers" WHERE "customers"."nickname" = '' LIMIT 1
(0.2ms) ROLLBACK
Может быть, это управление подтверждением того, что я уже на моем объекте клиента, но я не могу понять что это может быть. Это схема моего Заказчик:
create_table "customers", force: :cascade do |t|
t.string "email", default: "", null: false
t.string "encrypted_password", default: "", null: false
t.string "name", default: "", null: false
t.string "surname", default: "", null: false
t.string "nickname", default: "", null: false
...
end
Кто-то может мне помочь? Заранее спасибо
Я думаю, что моя проблема в том, что Facebook не возвращает электронное письмо, но я указал адрес электронной почты как область действия в devise initializer – Alfredo