开发者

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

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜