35

嗨,我来自 Grails 背景,是 Rails 的新手。我希望在 Rails 中进行 http 基本身份验证。

我在 grails 中有一个代码,它可以像这样进行基本身份验证:

def authString = "${key}:".getBytes().encodeBase64().toString()
def conn = "http://something.net".toURL().openConnection()
conn.setRequestProperty("Authorization", "Basic ${authString}")

可以用rails做同样的事情吗?

4

8 回答 8

92

在要限制使用 http 基本身份验证的控制器中编写以下代码

class ApplicationController < ActionController::Base
  http_basic_authenticate_with :name => "user", :password => "password" 
end

使用 open-uri 发出请求如下所示:

require 'open-uri'

open("http://www.your-website.net/", 
  http_basic_authentication: ["user", "password"])
于 2013-01-17T08:42:35.317 回答
22

在 Ruby on Rails 4 中,您可以根据上下文轻松地在站点范围内或每个控制器上应用基本的 HTTP 身份验证。

例如,如果您需要站点范围的身份验证:

class ApplicationController < ActionController::Base
  http_basic_authenticate_with name: "admin", password: "hunter2"
end

或基于每个控制器:

class CarsController < ApplicationController
  http_basic_authenticate_with name: "admin", password: "hunter2"
end
于 2013-12-27T04:25:59.557 回答
12

我赞成@Nishant 的回答,但想补充一点。您始终可以设置过滤器,使其仅通过传递onlyexcept类似方式应用于某些控制器操作:

http_basic_authenticate_with name: "admin", password: "strongpasswordhere", only: [:admin, :new, :edit, :destroy]

或者

http_basic_authenticate_with name: "admin", password: "strongpasswordhere", except: [:show]

在许多情况下非常有帮助。

于 2014-09-24T14:58:16.517 回答
7
# app/controllers/application_controller.rb
  before_filter :http_basic_auth

  def http_basic_auth
    if ENV['HTTP_AUTH'] =~ %r{(.+)\:(.+)}
      unless authenticate_with_http_basic { |user, password|  user == $1 && password == $2 }
        request_http_basic_authentication
      end
    end
  end

然后您只需要使用 user:password 导出环境变量,例如:

   export HTTP_AUTH=user:pass

如果您使用的是 heroku.com:

   heroku config:set HTTP_AUTH=user:pass
于 2015-04-21T20:17:33.407 回答
2

关于这个主题有一个很棒的 Rails Cast

http://railscasts.com/episodes/82-http-basic-authentication

于 2013-01-17T08:09:19.080 回答
2

当连接到受基本 HTTP 身份验证保护的 HTTP 端点时,我通常使用HTTPartyHTTParty是低 Ruby STD 类(如net/http )的简单包装器。

HTTParty与基本身份验证的示例用法。

class Delicious
  include HTTParty
  base_uri 'https://api.del.icio.us/v1'

  def initialize(u, p)
    @auth = {username: u, password: p}
  end

  def recent options={}
    options.merge!({basic_auth: @auth})
    self.class.get('/posts/recent', options)
  end
end

delicious = Delicious.new("<username>", "<password>")

pp delicious.recent #=> list of recent elements

在 GitHub 上查看更多示例。

于 2013-01-17T08:15:28.640 回答
2

以上答案是正确的,但最好不要将用户和密码放在源代码中。

最好在生产环境变量中有密码(在代码中可以用于开发)

class YourController..
  http_basic_authenticate_with name: ENV["HTTP_BASIC_AUTH_USER"], password: ENV["HTTP_BASIC_AUTH_PASSWORD"], if: -> { ENV['RAILS_ENV'] == 'production' }
  http_basic_authenticate_with name: "user", password: "pass", if: -> { ENV['RAILS_ENV'] != 'production' }
于 2020-02-11T15:07:34.343 回答
1

对于最新的 rails 版本,有一个ASCIIcast解释HTTP Basic Authentication的步骤。

链接在这里

旁注:请注意,HTTP 基本身份验证以明文形式传输用户名和密码,因此您不应将此方法用于需要更高安全级别的应用程序。

于 2013-01-17T08:18:02.433 回答