红宝石 1.9.2 + Sinatra - 需要在某些路由上进行身份验证

发布于 2024-12-11 17:40:26 字数 816 浏览 0 评论 0原文

在开始之前,这基本上是现有 ASP.MVC REST 风格服务到 Sinatra 的端口。我对 Ruby 还很陌生,所以还不太了解最佳实践,而且网络上在这个主题上似乎有点撕裂。

目前,在 ASP 风格中,我们有一些控制器,如下所示:

public class MyController : Controller
{
    [Authenticate]
    public ActionResult AccessSecretStuffs()
    {...}

    public ActionResult AccessPublicStuffs()
    {...}
}

现在,我们使用过滤器来确保任何带有 Authenticate 的操作在加载操作之前都会检查当前用户的身份验证。这些的路由设置相当普通,它们只是映射到控制器和操作。

现在,在使用 Sinatra 的 Ruby 领域,您往往不需要控制器,一切都是一个动作,而且由于我们纯粹希望以一种轻松的方式公开数据,这看起来很棒。然而,我需要能够确保每当使用 Sinatra 调用某些路由时,它基本上都会首先调用一些代码来检查它们是否可以访问该操作,如果不能访问该操作,则将它们重定向到登录页面。

我本想加入一些 AOP 来解决这个问题,但读了一会儿之后,每个人都说 Ruby 不需要 AOP,并且已经提供了大部分开箱即用的功能。那么有人可以阐明这样做的最佳实践吗?

Sinatra 文档有一个适用的 before 方法,但是我需要为每个其他路由方法执行一个 before 方法,这并不理想。在我看来,我只想声明一条路线,然后在末尾添加某种注释/属性,表明需要发生某些事情......

希望这有某种意义:)

Before I begin, this is basically a port of an existing ASP.MVC REST style service to Sinatra. I am fairly new to Ruby so dont really know the best practises yet, and the web seems a bit torn on the subject.

So currently in the ASP flavour we have some controllers like so:

public class MyController : Controller
{
    [Authenticate]
    public ActionResult AccessSecretStuffs()
    {...}

    public ActionResult AccessPublicStuffs()
    {...}
}

Now we use a filter to make sure that any actions with Authenticate check for authentication from the current user before loading the action. The routes setup for these are fairly vanilla, they just map to the controller and actions.

Now in Ruby land using Sinatra you dont tend to have controllers, everything is an action, and as we are purely looking to expose data in a restful way this seems great. However I need to be able to make sure that whenever certain routes are called with Sinatra that it will basically call a bit of code first to check if they can access the action, then if not redirect them to the login page.

I was thinking of just putting in some AOP to cover this, but after a bit of reading everyone says Ruby doesnt need AOP and already provides most of the functionality out of the box. So can anyone shed some light on the best practise for doing this?

Sinatra documentation has a before method that would be applicable, but then I would need to do a before method for every other route method, which isnt ideal. In my mind I just want to declare a route, and then put some sort of annotation/attribute at the end which indicates that something needs to happen...

Hope that makes some sort of sense :)

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

欲拥i 2024-12-18 17:40:26

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

或者如果您不需要传递任何参数,则 before 块可以将路径作为参数:

before '/secret/*' do
    authenticate!
end

您可以在 Sinatra 自述页面

Ruby doesn't have annotations as such, but Sinatra does provide custom filtering mechanisms.

When defining a route, you can put additional conditions, such as various header values and whatnot. You can also define custom conditions:

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

Then you can define a route like this:

get "/secret", :auth => [:user, :admin] do
    ...
end

or if you don't need to pass any arguments, before block can take a path as an argument:

before '/secret/*' do
    authenticate!
end

You can read more at Sinatra readme page

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文