How to move OpenID store to database instead of /tmp
We have a rails application that uses devise, and omniauth and wanted to support openID. We have it working on a single server, but it uses "/tmp" for it's "filesystem store". It seems like this wont work for multi application server environment.
How can we create 开发者_如何学JAVAa database store instead of the standard filesystem store? Better yet, is there a gem that will do it?
Thanks
There's actually a gem for this now: 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' }
)
Here are the steps:
1) create a table to store the authentication tokens: let's name it authentications
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) Modify the OmniauthCallbacksController::process_callback method (this is the method I used to process the all the callbacks from the OpenId and Facebook services) to create an authentication record and store it in the newly created authentications table:
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) go get a nice coffee since your are done.
Now note that the process_callbacks method depends by your application and it can be pretty complex. If you need more help with it just ask.
Hope this help
精彩评论