如何在 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
。
我不知道为什么我的 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
。