在RESTful响应中排除私有数据

时间:2010-07-12 19:27:24

标签: ruby-on-rails rest

如果请求RESTful响应的用户不能查看所有数据,那么排除某些字段/数据的最佳做法是什么?

示例:

名字姓氏出生日期

经过身份验证和未经身份验证的用户都可以向/people.xml发出RESTful请求以获取完整的人员列表。但是,只有经过身份验证的用户才能查看所有信息。未经身份验证的用户应仅返回名字和姓氏字段(不包括出生日期数据)。

Person控制器是否应该在构建响应之前检查身份验证?如果用户通过身份验证,他们会获得所有内容,否则他们只获得一个子集这会破坏REST的任何规则,其中/people.xml可以发送两个单独的结果吗?

5 个答案:

答案 0 :(得分:16)

不,那没关系。它是相同的资源,但基于身份验证信息具有不同的表示形式。您还可以根据Accept头包含的内容提供不同的版本(顺便说一下,您应该使用那个版本而不是文件扩展名,如.xml),或者您可以提供不同的语言版本,或者如果记录的话,您可以呈现不同的页面在用户中定义了特定的个性化选项。这都是合法的。考虑一个有登录框的网站。如果您已登录,则页面将有所不同。这是相同的,除了它不会特别影响所附信息本身。在这些情况下控制缓存等正是Cache-Control,Vary和朋友的目的。另请参阅http://www.subbu.org/blog/2007/12/vary-header-for-restful-applications

答案 1 :(得分:4)

相同的URL可以产生不同的表示形式,具体取决于请求标头。例如,响应的Accept is commonly used to control the format(例如,XML或JSON)。同样,authentication-headers可用于控制实体返回的数量。

答案 2 :(得分:0)

您可以使用:only方法的to_xml选项来限制控制器返回的字段,即:

def show
  @person = Person.find(params[:id])
  payload = current_user.nil? ? @person.to_xml(:only => 
                  [:first_name, :last_name, :dob]) : @person

  respond_to do |format|
    format.xml  { render :xml => payload }  
  end    
end

我使用serialize_with_options插件,因为大多数视图数据访问配置都可以在模型级别完成。

class Person
  serialize_with_options(:anonymous) do
    only   :first_name, :last_name, :dob
  end
end


class PersonController
  def show
    @person = Person.find(:params[:id])
    respond_to do |format|
      format.xml { render :xml => current_user.nil? ? @person.to_xml(:anonymous):
                             @person   }
    end    
  end
end

<强>参考

1 serialize_with_options

答案 3 :(得分:0)

如果在中间位置有缓存,请考虑相同数据的不同表示(取决于用户)会产生令人惊讶的后果。如果完全通过身份验证的用户首先发出请求,然后是“较小”用户,则可能会看到令人惊讶的结果:与之前完全通过身份验证的用户相同的视图。这是因为就缓存而言,这两个请求没有区别(除非你让它意识到这些问题)。所以,谨慎行事。

我还建议使用罗伯特提出的单独名称空间。

答案 4 :(得分:-3)

通过本书,REST说每个请求都应该返回一个资源。

我会创建一个名为“unauthenticated”的名称空间,然后创建

/people.xml用于经过身份验证的

/unauthenticated/people.xml

它们可以是为每个请求构建不同xml结果的相同控制器。