在开始之前,这基本上是对Sinatra的现有ASP.MVC REST样式服务的端口。我是Ruby的新手,所以还没有真正了解最佳实践,而且网络似乎对这个问题有点不了解。
所以目前在ASP风格中我们有一些像这样的控制器:
public class MyController : Controller
{
[Authenticate]
public ActionResult AccessSecretStuffs()
{...}
public ActionResult AccessPublicStuffs()
{...}
}
现在我们使用过滤器来确保在加载操作之前,使用Authenticate的任何操作都会检查当前用户的身份验证。这些路线设置相当普遍,它们只是映射到控制器和操作。
现在在使用Sinatra的Ruby土地上你不会有控制器,一切都是动作,而且我们纯粹希望以一种宁静的方式公开数据,这看起来很棒。但是我需要能够确保每当使用Sinatra调用某些路由时,它将首先调用一些代码来检查它们是否可以访问该操作,然后如果不将它们重定向到登录页面。
我当时正考虑加入一些AOP来解决这个问题,但经过一番阅读后,所有人都说Ruby不需要AOP,并且已经提供了大部分功能。那么,任何人都可以对这样做的最佳实践有所了解吗?
Sinatra文档有一个适用的before方法,但是我需要为每个其他路由方法做一个before方法,这不是理想的。在我看来,我只是想声明一个路线,然后在末尾添加一些注释/属性,表明需要发生的事情......
希望这有点道理:)
答案 0 :(得分:3)
Ruby没有这样的注释,但Sinatra确实提供了自定义过滤机制。
定义路径时,可以添加其他条件,例如各种标题值等等。您还可以定义自定义条件:
set(:auth) do |*roles| # <- notice the splat here
condition do
unless logged_in? && roles.any? {|role| current_user.in_role? role }
redirect "/login/", 303
end
end
end
然后你可以定义这样的路线:
get "/secret", :auth => [:user, :admin] do
...
end
或者如果您不需要传递任何参数,则在block之前可以将路径作为参数:
before '/secret/*' do
authenticate!
end
了解更多信息