使用浅路径保护rails API
我正在构建一个JSON api,它将成为另一个rails站点的数据源(使用devise for auth),并且具有基本的令牌认证工作。 API还将负责向移动应用程序提供数据。
在API中,我有以下模型:用户,书籍和章节用户has_many:书籍,书籍has_many:章节。 在我的路线文件中,我有
shallow do resources :users do resources :books do resources :chapters end end end
这导致如下路线:
/users/:user_id , /users/:user_id/books /books/:book_id , /books/:book_id/chapters /chapters/:chapter_id
即’浅路线’,而不是/ users /:user_id / books /:book_id / chapters /:chapter_id
我想知道我应该如何validation这些,因为该章不属于用户这不仅仅是检查user_id的情况(因为这是书模型的属性)。
# chapters_controller def show @chapter = Chapter.find(params[:id]) end
我是否必须得到@ chapter的书然后检查它的user_id? 不知怎的,对我来说感觉不对。 我是朝着错误的方向前进的吗?
谢谢阅读!
我发现一种技术可以让控制器建立一个模型范围,限制当前经过身份validation的用户可见/可更新/可销毁的内容。
我首先使用request_store gem在我的User
模型上设置我的控制器上的当前用户和请求信息,这只是一个小小的垫片,通过线程本地存储进行了一些清理。
这使得用户和请求信息可以通过User
类从我的任何模型中获得。 我在任何需要的地方都可以使用User.current
, User.request
和User.location
。
一旦对用户进行了身份validation,您的控制器就必须设置User.current
和User.request
。 这在构建模型中的范围时非常有用,因为它们可以限制当前用户可访问的范围。
您可以在模型上定义一个范围,如visible
,它可以在相关模型上执行where(:owner => User.current.id)
或类似的操作,以限制当前模型的可见/可更新/可销毁的内容。
然后,您的控制器只调用SomeModel.visible
, SomeModel.updateable
, SomeModel.destroyable
,它将获得一个限制为可读/写/销毁的范围。 任何基于该模型范围的find
只有在模型确实在用户的范围规则内时才会成功!
示例用户模型:
# models/user.rb require 'request_store' class User def self.current RequestStore.store[:current_user] end def self.current=(user) RequestStore.store[:current_user] = user end def self.request RequestStore.store[:current_request] end def self.request=(request) # stash the request so things like IP address and GEO-IP based location is available to other models RequestStore.store[:current_request] = request end def self.location # resolve the location just once per request RequestStore.store[:current_location] ||= self.request.try(:location) end end