我正在使用facebooker2(Rails 2.3和RESTFUlL身份驗證)進行facebook連接功能。在我的控制器中,我使用這個動作:Facebooker2如何保存一個新的註冊?
def create_facebook_user
if current_facebook_user
@user = User.find_by_fb_user_id(current_facebook_user.id.to_i)
end
if @user.blank?
@facebook_user = current_facebook_user.fetch
@user = User.new :login => @facebook_user.email, :email => @facebook_user.email, :name => @facebook_user.name
@user.fb_user_id = @facebook_user.id.to_i
@user.state = "active"
if @user.save(:validate=> false)
@user.profile = Profile.create(:benefactor_id => nil, :benefactor_invites => Setting.find_by_identifier("benefactor_invites").value.to_i)
redirect_to :controller => "profiles", :action => "show", :id => @user.profile.id
else
render "new"
end
elsif @user.fb_user_id.nil?
@user.update_attribute :fb_user_id, current_facebook_user.id
redirect_to :controller => "dashboard", :url => "index"
else
redirect_to :controller => "dashboard", :url => "index"
end
然後我的問題是給用戶分配狀態。當用戶使用save方法@ user.save(:validate => false)時,它不會「跳過」驗證器。另外我修改了一個RESTFul認證模塊「ByPassword」的方法password_required,但保存方法返回false。
我後我的代碼
Controller
class UsersController < ApplicationController
skip_before_filter :verify_authenticity_token, :only => :create
before_filter :find_user,
:only => [:profile,
:destroy,
:edit_password, :update_password,
:edit_email, :update_email]
layout 'application'
def create_facebook_user
if current_facebook_user
@user = User.find_by_fb_user_id(current_facebook_user.id.to_i)
end
if @user.blank?
@facebook_user = current_facebook_user.fetch
@user = User.new :login => @facebook_user.email, :email => @facebook_user.email, :name => @facebook_user.name
@user.fb_user_id = @facebook_user.id.to_i
@user.state = "active"
if @user.save(:validate=> false)
@user.profile = Profile.create(:benefactor_id => nil, :benefactor_invites => Setting.find_by_identifier("benefactor_invites").value.to_i)
redirect_to :controller => "profiles", :action => "show", :id => @user.profile.id
else
render "new"
end
elsif @user.fb_user_id.nil?
@user.update_attribute :fb_user_id, current_facebook_user.id
redirect_to :controller => "dashboard", :url => "index"
else
redirect_to :controller => "dashboard", :url => "index"
end
end
end
視圖(重要片段)
Øingresa CON Facebook連接 <%= fb_login_and_redirect( 「/用戶/ create_facebook_user」)%> <% #= fb_login_and_redirect('/ users/link_user_accounts',:perms =>'email,user_birthday')%> <%#= fb_login_button(「window.location ='/ users/link_user_accounts'「)%>
用戶模型
require 'digest/sha1'
class User < ActiveRecord::Base
include Authentication
include Authentication::ByPassword
include Authentication::ByCookieToken
include Authorization::AasmRoles
...
end
ByPassword模塊
module Authentication
module ByPassword
# Stuff directives into including module
def self.included(recipient)
recipient.extend(ModelClassMethods)
recipient.class_eval do
include ModelInstanceMethods
# Virtual attribute for the unencrypted password
attr_accessor :password
validates_presence_of :password, :message => :"user.password.blank", :if => :password_required?
validates_presence_of :password_confirmation, :message => :"user.password_confirmation.blank", :if => :password_required?
validates_confirmation_of :password, :message => :"user.password.confirmation", :if => :password_required?
validates_length_of :password, :within => 5..40, :message => :"user.password.too_short", :if => :password_required?
before_save :encrypt_password
end
end
# #included directives
#
# Class Methods
#
module ModelClassMethods
# This provides a modest increased defense against a dictionary attack if
# your db were ever compromised, but will invalidate existing passwords.
# See the README and the file config/initializers/site_keys.rb
#
# It may not be obvious, but if you set REST_AUTH_SITE_KEY to nil and
# REST_AUTH_DIGEST_STRETCHES to 1 you'll have backwards compatibility with
# older versions of restful-authentication.
def password_digest(password, salt)
digest = REST_AUTH_SITE_KEY
REST_AUTH_DIGEST_STRETCHES.times do
digest = secure_digest(digest, salt, password, REST_AUTH_SITE_KEY)
end
digest
end
end # class methods
#
# Instance Methods
#
module ModelInstanceMethods
# Encrypts the password with the user salt
def encrypt(password)
self.class.password_digest(password, salt)
end
def authenticated?(password)
crypted_password == encrypt(password)
end
# before filter
def encrypt_password
return if password.blank?
self.salt = self.class.make_token if new_record?
self.crypted_password = encrypt(password)
end
def password_required?
if fb_user_id.blank?
crypted_password.blank? || !password.blank?
else
return false
end
end
def has_fb_user_id?
fb_user_id.nil?
end
end # instance methods
end
end
你*有*使用Facebooker2嗎?我發現omniauth和考拉的組合很好。只是問,因爲我有可能有解決方案,如果你沒有使用Facebooker2的原因(例如在一個項目/團隊已經使用它)。 – justinxreese 2011-04-13 17:14:00