如何在 Rails 身份验证管道中为会话点击 'create' 而不是 'new'?

How to hit 'create' instead of 'new' for session in Rails auth pipeline?

我不知道为什么我的 Rails 身份验证管道只命中 new 而不是 create。这会导致登录页面重新呈现并且永远不会转到 search 页面。你能看看我的代码,看看我可能忽略了什么吗?

我正在使用 bcrypt 来散列 user

中的密码属性

我的routes

Rails.application.routes.draw do
  root :to => "searches#search" 

  resources :users, only: [:show, :new, :create, :destroy]

  get '/login', to: 'sessions#new', as: 'login'
  post '/login', to: 'sessions#create'

  delete '/logout', to: 'sessions#destroy', as: 'logout'

  get 'searches/index' => "searches#index"
  get 'searches/show' => "searches#show"
  get 'searches/search' => "searches#search" 


  get 'audits/show' => 'audits#show'     
  get 'audits/download' => 'downloads#show' 
  post 'audits/' => 'audits#create'

  # For details on the DSL available within this file, see https://guides.rubyonrails.org/routing.html
end 

application_controller

class ApplicationController < ActionController::Base
  before_action :authorized #lock down this whole app
  helper_method :current_user #i can call current_user from a view

  def current_user
    User.find_by({ id: session[:user_id] })
  end

  def logged_in?
    !!current_user
  end

  def authorized
    redirect_to login_path unless logged_in?
  end

end

sessions_controller

class SessionsController < ApplicationController
  skip_before_action :authorized, only: [:new, :create]

  def new
  end

  def create
    #handles the POST request to /login
    @user = User.find_by(username: params[:username])
    if @user && @user.authenticate(params[:password])
      session[:user_id] = @user.id
      redirect_to @user
    else
      flash[:notice] = 'Invalid username or password'
      redirect_to login_path
    end
  end

  def destroy
    session.delete(:user_id)
    flash[:notice] = 'logged out'
    redirect_to login_path
  end

end

sessions/new.html.erb

中的登录表单

<div class='login'>
    <div class="login-form">
        <form>
            <div class="form-group">
                <%= form_with url: login_path, method: 'post', local: true do |f|  %>
                    <%= f.label :username,  "Username", class: "col-md-4 control-label" %>
                    <%= f.text_field :username, class: "form-control", required: true %>
                    <%= f.label :password,  "Password", class: "col-md-4 control-label" %>
                    <%= f.password_field :password, class: "form-control", required: true %>
                    <%= f.submit "Login", class: "btn btn-default btn-primary" %>
                <% end %>
            </div>

        </form>
    </div>
</div>

我也试过 form_tag 但同样的问题。我将方法明确化只是为了确定,即使它不是必需的。

你可以把routes.rb改成:

Rails.application.routes.draw do
  # codes
  resources :sessions, only: [:create]
  get '/login', to: 'sessions#new', as: 'login'
  delete '/logout', to: 'sessions#destroy', as: 'logout'
  # codes
end

并将表单标签更改为

<%= form_with url: sessions_path, method: 'post', local: true do |f| %>

详情可以查看https://medium.com/@wintermeyer/authentication-from-scratch-with-rails-5-2-92d8676f6836

谢谢。

所以问题是我的 form_with 在 Bootstrap <form> 标签中。默认情况下,表单为 get