認証。acts_as_authenticatedとrole_requirementとopenid_login_generatorで、両対応な感じを目指す。
acts_as_authenticated
インスコ→じぇねる→migrate
$ ./script/plugin install acts_as_authenticated $ ./script/generate authenticated user account $ rake db:migrate
で、おk
role_requirement
インスコ→じぇねる→migrate
$ script/plugin install http://rolerequirement.googlecode.com/svn/tags/role_requirement/ $ script/generate roles Role User $ rake db:migrate
モデル書く
app/models/role.rb
class Role < ActiveRecord::Base has_and_belongs_to_many :users end
ロールの管理をscaffold
ruby script/generate scaffold role --skip-migration
migrationをskipしてるからか、スキーマ情報が
入ってないのでviewを直す。
(略)
openid_login_generator
既にgemでインスコしてあって、ジェネレータも直してる状態で、
generate
Userモデルはもうあるのでその辺はnで
$ ./script/generate openid_login openid create lib/openid_login_system.rb create app/controllers/openid_controller.rb create test/functional/openid_controller_test.rb create app/helpers/openid_helper.rb overwrite app/models/user.rb? (enter "h" for help) [Ynaqdh] n skip app/models/user.rb overwrite test/unit/user_test.rb? (enter "h" for help) [Ynaqdh] n skip test/unit/user_test.rb overwrite test/fixtures/users.yml? (enter "h" for help) [Ynaqdh] n skip test/fixtures/users.yml create app/views/layouts/scaffold.html.erb identical public/stylesheets/scaffold.css create app/views/openid create app/views/openid/welcome.rhtml create app/views/openid/login.rhtml create app/views/openid/logout.rhtml create README_LOGIN
usersにopenid_urlカラムを追加
$ ruby script/generate migration add_column_users_openid_url exists db/migrate create db/migrate/003_add_column_users_openid_url.rb
migarate_fileを編集
class AddColumnUsersOpenidUrl < ActiveRecord::Migration def self.up add_column :users, :openid_url, :string end def self.down remove_column :users, :openid_url end end
migrate
$ rake db:migrate (in /home/coek/dev/rails/auth_and_open_id_test) == 3 AddColumnUsersOpenidUrl: migrating ======================================= -- add_column(:users, :openid_url, :string) -> 0.0417s == 3 AddColumnUsersOpenidUrl: migrated (0.0439s) ==============================
モデル書き足す
def self.get(openid_url) find_by_openid_url(openid_url) end
protected validates_uniqueness_of :openid_url, :on => :create validates_presence_of :openid_url
で、controllerとかを
http://d.hatena.ne.jp/crimaru/20080212/1202793189
http://d.hatena.ne.jp/crimaru/20080212/1202812083
とかでやったように全部直す。
validateでコケる
今回はopenidからのログイン(登録)の場合は、idとopenid_urlだけ入れるってのでいいかなと思ってる。
で、普通にサインアップしたときは、openid_urlがNULLでいいかな、と。
なので
validates_presence_of :login, :email
だと、openidから使うときダメになるので
Userモデルに
def openid? self.openid_url.blank? #入ってたらfalseが返る end
なのを書き足して、
validates_presence_of :login, :email, :if => :openid? validates_presence_of :password, :if => :password_required? validates_presence_of :password_confirmation, :if => :password_required? validates_length_of :password, :within => 4..40, :if => :password_required? validates_confirmation_of :password, :if => :password_required? validates_length_of :login, :within => 3..40, :if => :openid? validates_length_of :email, :within => 3..100, :if => :openid? validates_uniqueness_of :login, :email, :case_sensitive => false, :if => :openid? (中略) validates_uniqueness_of :openid_url, :on => :create, :unless => :openid? validates_presence_of :openid_url, :unless => :openid?
な、感じでやればとりあえずよくなる。
とりあえずね。とりあえず。
あとpassword_required?もちょっとだけ手を入れる
def password_required? if openid? then crypted_password.blank? || !password.blank? else openid? end end
すんません。頑張ります><
これで一応両対応
http://localhost:3000/login/signup
から普通にサインアップ
http://localhost:3000/openid/
からOpenidログイン
usersに書かれる。
openid_controllerでのログイン処理
def complete #中略 when OpenID::Consumer::SUCCESS #中略 #OpenID::Consumer::SUCCESSの最後で #サイト側の認証 @user = User.get(oidresp.identity_url) if @user.blank? then @user = User.new(:openid_url => oidresp.identity_url) @user.save end self.current_user = @user redirect_to :action => 'mypage/top', :action => "index"