ROR 4 - 用户身份验证失败

时间:2015-10-22 17:06:33

标签: ruby-on-rails ruby ruby-on-rails-4 authentication

您好我是ROR 4的初学者,通过教程学习。现在我做了这个初学cms应用程序,但我无法使用我创建的登录页面再次登录它。我已经使用rails控制台检查了我输入的用户名和密码是真实的并存在于数据库中,我尝试通过控制台创建新用户,但我仍然无法登录应用程序。这让我疯了,无法登录你自己的应用程序。

这是我的登录页面代码

<% @page_title = "Admin Login" %>

<div class="login">
  <%= form_tag(:action => 'attempt_login') do %>
  <table>
    <tr>
      <td><%= label_tag(:username) %></td>
      <td><%= text_field_tag(:username) %></td>
    </tr>
    <tr>
      <td><%= label_tag(:password) %></td>
      <td><%= password_field_tag(:password) %></td>
    </tr>
    <tr>
      <td>&nbsp;</td>
      <td><%= submit_tag("Log In") %></td>
    </tr>
  </table>
  <% end %>
</div>

这是我的控制器代码

layout 'admin'

  before_action :confirm_logged_in, :except => [:login, :attempt_login, :logout]

  def index
    # display text & links
  end

  def login
    # login form
  end

  def attempt_login
    if params[:username].present? && params[:password].present?
      found_user = AdminUser.where(:username => params[:username]).first
      if found_user
        authorized_user = found_user.authenticate(params[:password])
      end
    end
    if authorized_user
      # mark user as logged in
      session[:user_id] = authorized_user.id
      session[:username] = authorized_user.username
      flash[:notice] = "You are now logged in."
      redirect_to(:action => 'index')
    else
      flash[:notice] = "Invalid username/password combination."
      redirect_to(:action => 'login')
    end
  end

  def logout
    # mark user as logged out
    session[:user_id] = nil
    session[:username] = nil
    flash[:notice] = "Logged out"
    redirect_to(:action => "login")
  end

end

非常感谢这件事的帮助。

1 个答案:

答案 0 :(得分:0)

首先 - 不要将您的身份验证放入UsersController或ApplicationController。这是重要的事情。它值得拥有自己的控制器。

同样在Rails中,宁静的CRUD约定非常重要。那么您如何将用户登录视为资源呢?

class SessionsController < ApplicationController
  # display the form to sign a user in
  # GET /session/new
  def new
    @user = AdminUser.new
  end

  # verify that the user is who he says he is and log them in.
  # POST /session
  def create
     reset_session
     @user = AdminUser.find_by(username: admin_user_params[:username])
     if @user && @user.authenticate(admin_user_params[:password])
        session[:user_id] = @user.id
        redirect_to root_path, notice: "You are now logged in."
     else
        flash.now[:error] = "Invalid username/password combination."
        @user = AdminUser.new 
        render :new 
     end
  end

  # sign a user out
  # DELETE /session
  def destroy
    reset_session
    redirect_to root_path, notice: "You have been signed out."
  end

  private

    def admin_user_params
      params.require(:admin_user).permit(:password, :username)
    end
end

请注意,我们在登录前调用reset_session并注销。这会使会话密钥无效 - 这可以防止一种称为会话固定的漏洞,攻击者窃取您的用户cookie。

另请注意,我们不区分用户输入错误的用户名或密码的时间。这是一种防止彩虹攻击的方法,黑客首先猜测用户名,然后使用包含常用密码的彩虹表来闯入暴力。这使得猜测用户名更加困难。

但我们还需要一些路线:

# config/routes.rb
Rails.application.routes.draw do
  # ...
  resource :session, only: [:new, :create, :destroy]
end

请注意,我们使用单数资源。这是因为从用户的角度来看,只有一个会话 - 他们自己的。

我们还需要一个表单(views/session/new.html.erb):

<%= form_for(@user, url: { action: :create, controller: :sessions }) do |f| %>
  <%= f.text_field :username %>
  <%= f.password_field :password %>
  <%= f.submit "Log in" %>
<% end %>