【问题标题】:Ruby On Rails authentication issue with http basic(the authentication process is triggered twice for every request)Ruby On Rails 的 http basic 身份验证问题(每个请求都会触发两次身份验证过程)
【发布时间】:2015-12-15 09:04:31
【问题描述】:

这是我发送给 rails 控制器的请求:

function login(){ 
 $.ajax({
    type: 'GET',
    url: '/api/myapi/show',
    username: 'username',
    password: 'password',
    contentType: "application/json; charset=utf-8",
    success: function(data){
      console.log(data);
    },
    error: function(xhr, ajaxOptions, thrownError) {
      console.log(arguments);
    }
  });
 }

登录功能使用如下:

<body onload='login();'>

这是控制器:

class Api::MyApi::BaseController < ApplicationController
  before_filter :authenticate
  attr_reader :user

  def authenticate
    authenticate_or_request_with_http_basic do |username, password|
        #authenticate method checks if user with username and password exists in database
        @user = User.authenticate(username, password)
    end
  end
end

当我发送请求时,终端打印的内容如下:

Started GET "/api/myapi/show" for 127.0.0.1 at 2015-12-15 09:42:22 +0100
Processing by Api::MyApi#show as JSON
  Parameters: {"id"=>"show", "test"=>{}}
Filter chain halted as :authenticate rendered or redirected
Completed 401 Unauthorized in 0ms (ActiveRecord: 0.0ms)


Started GET "/api/myapi/show" for 127.0.0.1 at 2015-12-15 09:42:22 +0100
Processing by Api::MyApi#show as JSON
  Parameters: {"id"=>"show", "test"=>{}}
  User Load (0.1ms)  SELECT `users`.* FROM `users` WHERE `users`.`authorized` = 1 AND `users`.`verification_approved` = 1 AND `users`.`login` = 'user_login' LIMIT 1
  Location Load (0.1ms)  SELECT `locations`.* FROM `locations` WHERE `locations`.`id` = 9999 LIMIT 1
  Rendered api/myapi/show.json.rabl (0.5ms)
Completed 200 OK in 8ms (Views: 2.6ms | ActiveRecord: 0.7ms)

如您所见,它尝试进行两次身份验证,第一次失败。它甚至没有进入“authenticate_or_request_with_http_basic”,因为如果我在“authenticate_or_request_with_http_basic”中编写打印语句,它不会在第一次打印(当身份验证失败时),但会在第二次打印。

我尝试过的事情:

1) 完全移除 before_filter 并仅在 show 方法中进行身份验证时,不再出现此问题。

2) 保留/使用 before_filter 但将 authenticate_or_request_with_http_basic 替换为 'true' 时,如下所示:

def authenticate
 true
end 

这个问题也不会发生。

3) 当我使用 python 发送请求时不会出现该问题:

import requests
r = requests.get('URL_TO__RoR_Controller', auth=('username', 'password'))
print r.text

更新: 这可能是有用的信息:请求每 10 秒发送一次,并且凭据随每个请求一起发送。也许这与问题有关。

【问题讨论】:

  • 在您的 jquery 方法的开头添加 event.preventDefault()
  • 似乎不起作用。
  • 能否提供完整的js/jquery方法?
  • 查看我的编辑(内容不多)。

标签: ruby-on-rails ruby authentication basic-authentication before-filter


【解决方案1】:

您将用户名和密码作为参数发送

AFAIK 基本身份验证通过设置授权标头来工作

使用 jQuery 的 beforeSend 回调添加带有身份验证信息的 HTTP 标头:http://api.jquery.com/jQuery.ajax/

beforeSend: function (xhr) {
  xhr.setRequestHeader ("Authorization", "Basic " + btoa(username + ":" + password));
},

btoa() 方法以 base-64 编码字符串。

在您的控制器中,您可以使用

检查标题
request.env["HTTP_AUTHORIZATION"]

让我知道这是否适合你。

【讨论】:

  • 请求是由第三方 .Net 应用程序发送的,这也会导致我的问题中描述的身份验证问题。如果问题是由第三方 .Net 应用程序引起的,或者是控制器中的错误,我只是在使用 ajax 请求进行测试。我确实尝试了你的建议,但没有奏效。我在终端中得到完全相同的输出。此外,当像这样硬编码用户名和密码时: btoa("my_username:my_password") 显示身份验证弹出屏幕。
猜你喜欢
  • 1970-01-01
  • 2011-12-05
  • 2011-02-02
  • 1970-01-01
  • 2020-10-31
  • 2016-05-14
  • 2018-04-27
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多