2012-11-03 61 views
0

我使用omniauth-twitter和我一切設置:使用戶當他們與Twitter(OmniAuth)登錄進入他們的電子郵件

user.rb:

def self.create_with_omniauth(auth) 
    create! do |user| 
     user.provider = auth["provider"] 
     user.uid = auth["uid"] 
     user.name = auth["info"]["name"] 
     user.email = auth["info"]["email"] 
     # To pass password validation 
     user.password = user.password_confirmation = SecureRandom.urlsafe_base64(n=6) 
    end 
    end 

sessions_controller.rb :

def create 
    user = User.find_by_email(params[:session][:email].downcase) 
    if user && user.authenticate(params[:session][:password]) 
     sign_in user 
     redirect_back_or user 
    else 
     flash.now[:error] = 'Invalid email/password combination' 
     render 'new' 
    end 
    end 

的問題是,你不能檢索來自Twitter的電子郵件地址,因此T他登錄失敗,因爲我的驗證規則:

user.rb:

before_save { |user| user.email = email.downcase } 
    before_save :create_remember_token 

    validates :name, presence: true, length: { maximum: 50 } 
    VALID_EMAIL_REGEX = /\A[\w+\-.][email protected][a-z\d\-.]+\.[a-z]+\z/i 
    validates :email, presence: true, 
        format:  { with: VALID_EMAIL_REGEX }, 
        uniqueness: { case_sensitive: false } 
    validates :password, presence: true, length: { minimum: 6 } 
    validates :password_confirmation, presence: true 

我想,使用戶能夠輸入一個電子郵件,以便他們可以在沒有失敗的驗證(僅與Twitter登錄,因爲我也有Facebook和Google登錄)。

有沒有人有任何建議?

編輯:

users_controller.rb:

def create 
    @user = User.new(params[:user]) 
    if @user.save 
     sign_in @user 
     flash[:success] = "Welcome to the Sample App!" 
     redirect_to @user 
    else 
     if params[:form_name] == "enter_email" 
     render 'enter_email' 
     else 
     render 'new' 
     end 
    end 
    end 

用戶/ enter_email.html.erb:

<% provide(:title, 'Enter your email') %> 
<h1>Enter your email</h1> 

    <div class="row"> 
     <div class="span6 offset3"> 
     <%= form_for(@user) do |f| %> 
      <%= render 'shared/error_messages', object: f.object %> 

      <%= f.label :email %> 
      <%= f.text_field :email %> 

      <%= f.hidden_field :provider, value: params[:oprovider] %> 
      <%= f.hidden_field :provider, value: params[:oprovider] %> 
      <%= f.hidden_field :uid, value: params[:ouid] %> 
      <%= f.hidden_field :name, value: params[:oname] %> 
      <%= f.hidden_field :password , value: params[:opassword] %> 
      <%= f.hidden_field :password_confirmation, value: params[:opassword_confirmation] %> 

      <% # To know to which form to redirect in case of validation error %> 
      <%= hidden_field_tag 'form_name', 'enter_email' %> 

      <%= f.submit "Create my account", class: "btn btn-large btn-primary" %> 
     <% end %> 
     </div> 
    </div> 

回答

1

當用戶創建這將是無效,因爲它將丟失所需的電子郵件。因此,當用戶保存失敗時,您應該將您從Twitter中檢索到的信息放入會話中,並將用戶重定向到註冊頁面,以便在其中輸入他的電子郵件。基本上,這個:

# SessionsController 
def create 

    if user.save 
    sign_in user 
    redirect_to ... 
    else 
    session[:omniauth] = request.env['omniauth.auth'].except('extra') 
    redirect_to new_registration_path 
    end 

end 

你會發現,我們丟棄extra散列,因爲它通常包含了很多我們並不需要的信息。如果您確實需要它,請小心,因爲會話具有一定的大小限制,有時您無法容納所有內容。

現在,您需要創建一個new行動登記控制器(顯示一個頁面,用戶將輸入他的電子郵件)和create動作(在這裏您將使用Twitter的信息,以進一步自定義您的新用戶)。

# RegistrationsController 
def create 
    if session[:omniauth] 
    user = User.create_with_email_and_omniauth(params[:user], session[:omniauth]) 
    end 
    session[:omniauth] = nil unless user.new_record? 
end 

最後,如果用戶有效並保存,那麼我們可以安全地銷燬會話中的Twitter信息。

+0

我必須創建一個新的'registration'控制器嗎?由於我已經有了一個「用戶控制器」和一個「創建」動作,我可以使用它嗎?對不起,我對Rails有點新鮮,我怎樣才能將上面提供的代碼與'ent​​er_email'形式結合使用? (請參閱我的**編輯**) – alexchenco

+0

嗯......我想我必須在用戶的控制器中創建一個'create_with_omniauth'動作,對吧?並在表單中使用該操作? – alexchenco

+0

是的,您的控制器不必被命名爲'registrations',那只是一個建議。現在,你可以使用'用戶控制器',但它可能取決於很多事情。 「創建」動作何時被調用?這非常重要。 – Ashitaka

相關問題