简体   繁体   中英

How to prevent directly sending the post request in the backend in rails?

I am currently have a form that search for a registrant and has a validation on the front-end to verify that all required fields are filled out, which it throws an error all the fields are left blank after submitting, BUT when anyone send a direct POST request(without using the ui) they can bypass all the required field. I have been told that I should specify a validation so that it can prevent someone sending direct POST request through other means such as postman.

Here is my current controller:

class RegistrantsController < ApplicationController 

before_action :set_search, only: %i[search_by_name] 

def search_by_name
    authorize Registrant, :search?
    session.delete(:search_for_patient)
    if search_params[:first_name].present? && search_params[:last_name].present? && search_params[:date_of_birth].present?
      @registrants = Registrant.search_by_name(search_params.transform_values(&:strip))
    end
    
    respond_to do |format|
      format.html { render 'search'}
      format.js { render partial: 'patient_search_result'}
    end
  end

private

 def search_params
    params.permit(:first_name, :last_name, :date_of_birth, :identification_type, :identification_number)
  end

 def set_search
    @q = Registrant.ransack(params[:q]&.transform_values(&:strip))
    @registrants = params[:q] ? @q.result : nil
    @patient = Registrant.find(session[:patient_id_to_add_caregiver]) if session[:patient_id_to_add_caregiver]

    hospice_id = session[:hospice_id_to_add_caregiver] || session[:hospice_id_to_add_patient]
    @hospice = Hospice.find(hospice_id) if hospice_id
  end


end

Im not sure if that's enough information but let me know if more information need to be clarified. Thank you

UPDATE:

Here is the route:

match 'registrants/search_by_name',
        to: 'registrants#search_by_name',
        as: 'name_search_registrants',
        via: [:get, :post]

One of the solutions would be to change the code in your controller to something like this:

  def search_by_name
    # some code omitted
    if search_params[:first_name].present? && search_params[:last_name].present? && search_params[:date_of_birth].present?
      @registrants = Registrant.search_by_name(search_params.transform_values(&:strip))
      respond_to do |format|
        format.html { render 'search' }
        format.js { render 'patient_search_result'}
      end
    else
      flash[:alert] = "Please provide all the data required for a search"
      respond_to do |format|
        format.html { render 'search_error' }
        format.js { render 'search_error' }
      end
    end
  end

Then, you would have to create two new views to display the error to a user. The simplest way would be something like this:

  1. app/views/registrants/search_error.html.erb
  <div><%= flash[:alert] %></div>
  1. app/views/registrants/search_error.js.erb
  alert('<%= flash[:alert] %>');

Of course in production it should be a bit more user friendly but my code can be extended a bit to achieve that.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM