使用SQL外键约束来阻止Rails用户操纵



您好我的SQL和/或Rails Friends。

假设我们有两个型号:

class Hostel < ActiveRecord::Base
  has_many :beds
end
class Bed < ActiveRecord::Base
  belongs_to :hostel
end

当我的用户(旅馆所有者)尝试创建新预订时,参数会像这样:

{bed_id:12,start_date:" 2017-10-13",end_date:" 2017-10-15",...}

BED_ID 来自下拉菜单,显示所有Current_user的床名。ID随其余表单数据传递。现在,在BookingsController中,我必须手动确保黑客不会操纵 bed_id 变量到他们不拥有的床上。

class BookingsController < ApplicationController
  def create
    @bed = current_user.beds.where(id: params[:bed_id]).first 
    if @bed
      # create hostel booking
    else
      # this happens when the user willfully changes the bed_id
      # number using DevTools
    end
end

我不介意以这种方式验证用户输入,但是我想知道是否有一种方法可以利用SQL和/或外键约束来确保用户不会使用不使用的床来创建预订'T属于他们?

这是一些pidgin sql,说明了我想要的东西。基本上,使数据库验证 bed_id 使用的 user_id 是Current_user的ID。

INSERT INTO bookings (start_date, end_date, bed_id, user_id)
VALUES ("2017-10-13", "2017-10-15", 12, 1)
UNLESS (SELECT * FROM beds WHERE id = 12).user_id != current_user.id
# what I'm doing above is verifying that bed #12 has a user_id that 
# is the same as the current user's ID. That way, if a user 
# manipulates the params, SQL catches it.

编辑:这是一个更好的问题:

在铁轨中,我可以打开控制台并手动创建新的预订:

Booking.new(user_id: 1, bed_id: 12, start: "2017-10-13", end: "2017-10-15")

和数据库将创建记录,即使具有ID#12的床不属于用户#1。无论如何是否可以使SQL加强这些约束?

我知道这不是问什么,而是...我首选的解决方案是在轨道上进行操作,这使您可以更好地控制并独立于平台。

(对不起,我不能轻易验证它,但应该给您这个想法)

class BookingsController < ApplicationController
before_action :check_authorisation, only: :create
def check_authorisation
    unless current_user.beds.where(id: params[:bed_id]).first
        flash[:danger] = "You are not authorised to access this section"
        redirect_to home_url # halts request cycle need to adjust home_url to appropriate
    end
end

最新更新