如何验证我的控制器操作是从我的Rails应用程序中调用的

时间:2016-01-14 22:57:56

标签: ruby-on-rails ajax validation

我有一个简单的用户注册表单。

当用户填写表单并点击“#34;提交"我有一个JavaScript事件拦截提交,并使用AJAX调用下面的validate方法来检查表单数据,然后再提交。如果表单数据正常,则继续提交,但如果不是,则取消提交并在页面上显示警告。这是进行实时客户端验证的简单方法。

# app/controllers/users_controller.rb

# Validates the form data. Returns an error message response in the format
#   { response: "Invalid email format!" }
#
# A blank response means success
#
def validate
  if request.xhr? || <request came from another method in this controller>
    # Run various validations on input data and determine a response
    # response_text = ...
    render json: { response: response_text }
  else
    redirect_to root_path
  end
end

def create
  if JSON.parse(validate)["response"].blank?
    User.create(...)
    # Other stuff
  end
end

但是,当提交最终通过并通过时,它会向POST操作发送create以创建新的User。该方法再次调用validate (重新验证的成本最低),以确保没有人绕过表单并直接向服务器提交恶意请求。

所以我的validate方法必须同时响应(a)AJAX调用和(b)&#34;内部&#34;来自应用内的来电。对validate操作的所有其他调用应该只重定向到根路径。

我可以使用request.xhr?判断调用是否是一个非常简单的AJAX调用。

  1. 如何检查操作是在内部调用而不是由用户调用?

  2. 退后一步,这是一个很好的验证通用方法吗?有什么想改进吗?

  3. 谢谢!

3 个答案:

答案 0 :(得分:2)

只要用户查看表单并将其作为随机字符串存储在HTML中,

Rails就会生成authenticity token。该令牌也存储在会话中,因此对用户不可见。收到请求后,您的应用程序将比较令牌以验证请求是否是从您的表单生成的。

TL; DR:别担心,你已经受到保护了。

答案 1 :(得分:1)

我没有具体的答案,但有一些可能有用的信息。如果需要,我很乐意删除它......

  

AJAX调用和&#34;内部&#34;电话

您必须了解XHR请求只能 来自您的应用 - CORS (cross origin resource sharing)

Ajax调用只能来自您自己的域名,因此不要认为恶意黑客可以运行某些刮刀或其他任何 - you choose允许哪些域发送XHR请求。

所以,当你打电话......

x,y,w,h = crdn
check_box = crop[y:y+h,x:x+w]
check_box_img_gray = cv2.cvtColor(check_box, cv2.COLOR_BGR2GRAY)
(_, thresh) = cv2.threshold(check_box_img_gray,200,255,cv2.THRESH_BINARY)
height,width = thresh.shape[:2]
tot_px = height * width
checked_box =  cv2.countNonZero(thresh) / float(tot_px)
if checked_box < 0.6: 
    print "Found"

...作为验证的一部分,您需要在使用XHR时确定范围。

在同一张纸条上,您正在进行哪些验证?

如果您正在验证输入数据,Rails会在模型层处理此问题。我们已完成something similar(点击登录/注册顶部):

enter image description here

Rails的基本结构为MVC,这意味着您的if request.xhr? 仅负责接收请求&amp;从中构建适当的数据对象。

因此,如果您正在验证&#34;输入,除了数据本身(由模型处理)还有什么可以验证?

enter image description here

当指定controller时,Rails使用CSRF令牌为表单提交提供某些级别的身份验证。

-

您可以轻松使用以下内容:

@MarsAtomic

如果您之后将请求作为#app/controllers/users_controller.rb class UsersController < ApplicationController respond_to :js, :json, :html def create @user = User.new user_params respond_with @user.save end end 从前端发送,则您将获回创建的用户或错误:

json

答案 2 :(得分:0)

在您的create方法中,如果它无效(如果它们跳过ajax验证),您希望返回@user

如果是这种情况,您不想执行User.create,而是创建一个实例并尝试保存它。如果你做了这一切,你正在为create做正常的控制器动作,不需要在内部调用validate。

def create
  @user = User.new(user_params)
  if @user.save
    # Other stuff
  end
end

而且,创建一个json响应并解析它以查看对象是否有效并不是一个好习惯。相反,要么测试有效吗?或者只是尝试保存并找回真假。

换句话说 - 将您的验证方法与您的create方法分开。他们最终都会依赖valid?