【问题标题】:Prevent Authlogic from establishing a session/cookie for non-HTML requests防止 Authlogic 为非 HTML 请求建立会话/cookie
【发布时间】:2011-01-06 14:30:55
【问题描述】:

我正在使用 Authlogic 和 Rails 3。除了常规的基于浏览器的用户体验(通过表单等登录)之外,我还想实现一个 API。

Authlogic 似乎支持默认情况下不持久的单一访问令牌。我通过添加 GET 参数来提供它们,如下所示:

/users.xml?user_credentails=my_single_access_token

问题:有什么方法可以让 Authlogic 通过 HTTP Basic Auth 接受 API 密钥? Highrise 做了这样的事情,允许:

curl -u 605b32dd:X http://sample.highrisehq.com/people/1.xml

Freshbooks:

curl -u insert_token_here:X https://sample.freshbooks.com/api/2.1/xml-in -d '[xml body here]'

我将如何去模仿这个功能?我什至无法弄清楚输入数据(来自表单的 postdata、HTTP 基本、API 令牌)的接收位置。我将其归结为对 UserSessions.find 的不带参数的调用,但之后我就忘记了它在那里。

任何帮助将不胜感激!

相关问题:如果使用 HTTP 基本,我还想禁用会话持久性(使其不存储 cookie)。对此的任何帮助也将不胜感激!

【问题讨论】:

    标签: ruby-on-rails api authlogic


    【解决方案1】:

    如果您正在实施 API,您可以考虑构建一个单独的 Rack 应用程序,然后将其安装在“/api/1.0/...”并共享您的模型。

    这样您就不会将自己的 API 与您的公共路由直接相关,而这对于 API 用户来说可能很难构建。

    一个好的方法是创建一个简单的 Sinatra 应用程序,只公开您想要的方法,然后创建一个单独的身份验证策略:

    require 'sinatra'    
    require 'active_support' # all the Rails stuff
    require 'lib/user' # your User class
    require 'sinatra/respond_to' # gem install sinatra-respond_to
    
    Sinatra::Application.register Sinatra::RespondTo
    
    use Rack::Auth::Basic, "API", do |username, password|
      User.find_by_login(username).valid_password?(password)
    end
    
    get '/api/1.0/posts' do
      @posts = Post.recent # assuming you have a Post model...
    
      respond_to do |wants|
        wants.xml { @posts.to_xml }
        wants.to_json { @posts.to_json }
      end
    end
    
    get '/api/1.0/users/:id' do
      @user = User.find_by_login(params[:id])
    
      # Careful here - don't release personal details!
      respond_to do |wants|
        wants.xml { @user.to_xml }
        wants.to_json { @user.to_json }
      end
    end
    

    在路径中使用“1.0”(或类似名称)对您的 API 进行版本控制意味着,如果您更改模型,则可以在不破坏用户现有代码的情况下创建新版本的 API。

    使用它,您应该能够允许用户以以下形式使用 HTTP Basic 进行身份验证:

    curl -u steven:password http://example.com/api/1.0/users/steven.xml
    curl -u steven:password http://example.com/api/1.0/users/steven.json
    curl -u steven:password http://example.com/api/1.0/posts.xml
    

    要使其运行,请将其保存为“api.rb”,然后将其作为机架中间件运行,或者像这样创建一个“config.ru”文件:

    require 'api'
    run Sinatra::Application
    

    然后从那个目录:

    rackup
    

    【讨论】:

    • 感谢 stef,您撰写了关于 Rails 环境中 API 设置的精彩文章,尽管它对我手头的问题没有多大帮助:当单一访问令牌/API 是时如何验证用户在 HTTP 基本身份验证字符串中提供。
    • 哦,我明白了 - 您想使用令牌而不是密码...更新以反映这一点。
    • 感谢 stef,您对设置 API 的另一种方法的详细回答和评论。为此,我支持你。但是我的问题(明确地说,如何强制 Authlogic 执行这个特定功能)仍然没有得到解决。我会继续自己调查。
    【解决方案2】:

    免责声明:我不是 100%,这在您描述的方式中是可能的,而不会破坏 Authlogic 的核心功能。

    您遇到的第一个问题是 authlogic 会阻止使用 SSO 令牌进行身份验证,除非请求是 ATOM 或 RSS 来覆盖它,您需要传递配置参数,请参见此处:http://rdoc.info/github/binarylogic/authlogic/master/Authlogic/Session/Params/Config

    核心问题:我没有看到任何“简单”的方法来处理此功能,但是您可以为 curl 之类的东西做的是将用户令牌作为参数传递(使用 -G 选项)就像您在访问网址时会这样做。

    cURL 文档:http://curl.haxx.se/docs/manpage.html

    【讨论】:

    • 在站点范围内允许单一访问令牌/API 密钥似乎就像让控制器的 single_access_allowed? 方法返回 true 一样简单。
    【解决方案3】:

    如果我误解了您的问题,请原谅我,但我认为答案是简单的“不”。你在这里混合了两个隐喻。如果您想要一个安全的 API 密钥,请使用单一访问令牌;如果您想使用 http 基本访问身份验证,则需要一个不同的 base64 字形 - 而 http 基本身份验证并不是特别安全(除非通过 https 使用,这通常不实用)。

    更详细的:

    根据维基百科,http basic authentication 旨在以简单、标准但相当不安全的 base64 编码字形提供用户名和密码。

    要使用基本身份验证,那么我相信您想通过简单的方式生成字形

    Base64.encode64("#{user.name}:#{password}")
    

    ...我可能会通过让用户输入他们的密码来做到这一点,因为您无法从 authlogic 存储在数据库中的 crypted_pa​​ssword 派生密码。

    但结果是,这和single_access_token是截然不同的野兽,两者不能混为一谈。

    【讨论】:

    • 启用单一访问令牌作为 HTTP 基本用户名(使用虚拟密码)在我看来并不比接受单一访问令牌作为查询字符串的默认 Authlogic 做法安全.仅供参考,SSL 被用于所有经过身份验证的请求,但该细节超出了我的正确问题的范围。为了澄清我的问题,我不希望将用户名/密码身份验证与 API 密钥“结合”;我只想告诉 Authlogic 在通过 HTTP Basic 提供 API 密钥时接受它,而不是作为查询字符串属性。
    • 我的意思是,如果您使用实际的用户名和密码,我认为它会开箱即用。关于安全的公平点。我也不会使用原始的单一访问令牌。
    • 我对 single_access_key 感到困扰; AuthLogic 不会提供更好的安全性,这听起来很不对劲。所以我做了更多的研究。这篇文章 --stackoverflow.com/questions/1691330/validate-api-with-authlogic -- 在这方面让我放心,看起来它可以为您提供解决问题所需的信息。
    猜你喜欢
    • 2011-11-05
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-01-03
    • 1970-01-01
    • 1970-01-01
    • 2023-03-06
    • 1970-01-01
    相关资源
    最近更新 更多