Как переместить хранилище OpenID в базу данных вместо /tmp
У нас есть приложение rails, которое использует devise и omniauth и хочет поддержать openID. Он работает на одном сервере, но использует "/tmp" для "хранилища файловой системы". Кажется, что это не будет работать для среды с несколькими серверами приложений.
Как мы можем создать хранилище базы данных вместо стандартного хранилища файловой системы? А еще лучше, есть ли драгоценный камень, который сделает это?
Спасибо
2 ответа
На самом деле для этого сейчас есть жемчужина: https://github.com/TheNeatCompany/openid-activerecord-store
# Omniauth example:
Rails.application.config.middleware.use(
OmniAuth::Strategies::GoogleApps,
OpenID::Store::ActiveRecord.new,
{ :name => 'example', :domain => 'example.org' }
)
Вот шаги:
1) создать таблицу для хранения токенов аутентификации: назовем ее аутентификации
class CreateAuthentications < ActiveRecord::Migration
def self.up
create_table :authentications do |t|
t.integer :user_id
t.string :provider
t.string :uid
t.string :provider_name
t.string :provider_username
t.text :token
t.timestamps
end
add_index :authentications, :user_id
add_index :authentications, :provider
add_index :authentications, :uid
add_index :authentications, :token, :unique=>true
end
def self.down
drop_table :authentications
end
end
2) Измените метод OmniauthCallbacksController::process_callback (этот метод я использовал для обработки всех обратных вызовов из служб OpenId и Facebook), чтобы создать запись аутентификации и сохранить ее во вновь созданной таблице аутентификаций:
def process_callbacks
# ...some code here
# Find if an authentication token for this provider and user id already exists
authentication = Authentication.find_by_provider_and_uid(@omniauth_hash['provider'], @omniauth_hash['uid'])
if authentication # We found an authentication
if user_signed_in? && (authentication.user.id != current_user.id)
flash[:error] = I18n.t "controllers.omniauth_callbacks.process_callback.error.account_already_taken",
:provider => registration_hash[:provider].capitalize,
:account => registration_hash[:email]
redirect_to edit_user_account_path(current_user)
return
end
else
# We could not find the authentication than create one
authentication = Authentication.new(:provider => @omniauth_hash['provider'], :uid => @omniauth_hash['uid'])
if user_signed_in?
authentication.user = current_user
else
registration_hash[:skip_confirmation] = true
authentication.user = User.find_by_email(registration_hash[:email]) || User.create_user(registration_hash)
end
end
@user = authentication.user
# save the authentication
authentication.token = @omniauth_hash
authentication.provider_name = registration_hash[:provider]
authentication.provider_username = registration_hash[:email]
if !authentication.save
logger.error(authentication.errors)
end
#...more code here
end
3) иди принеси хороший кофе, так как все готово.
Теперь обратите внимание, что метод process_callbacks зависит от вашего приложения и может быть довольно сложным. Если вам нужна дополнительная помощь, просто спросите.
Надеюсь это поможет