使用http basic的Ruby On Rails身份验证问题(每个请求都会触发两次身份验证过程)

时间:2015-12-15 09:04:32

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

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

<!DOCTYPE html>
<html ng-app="demoApp">
<head>
  <link rel="stylesheet" href="https://rawgit.com/angular/bower-material/v1.0.0/angular-material.css">

  <script src="//rawgit.com/angular/bower-angular/master/angular.js"></script>
  <script src="//rawgit.com/angular/bower-angular-aria/master/angular-aria.js"></script>
  <script src="//rawgit.com/angular/bower-angular-animate/master/angular-animate.js"></script>
  <script src="//rawgit.com/angular/bower-material/v1.0.0/angular-material.js"></script>
  <script src="//rawgit.com/angular-ui/ui-router/master/release/angular-ui-router.js"></script>
  <meta charset="utf-8">
  <title>Example</title>
</head>
  
<body>
  
  <div ui-view></div>
  
</body>
</html>

登录功能使用如下:

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

如您所见,它尝试进行两次身份验证,并在第一次失败。它甚至没有进入内部&#34; authenticate_or_request_with_http_basic&#34;因为如果我在&#34; authenticate_or_request_with_http_basic&#34;中写了一个print语句,它第一次就没有打印(当验证失败时),但是第二次打印。

我尝试的事情:

1)完全删除before_filter并仅在show方法中进行身份验证时,问题不再发生。

2)保持/使用before_filter但将authenticate_or_request_with_http_basic替换为&#39; true&#39;像这样:

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)

这个问题也没有发生。

3)当我使用python发送请求时,问题不会发生:

def authenticate
 true
end 

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

1 个答案:

答案 0 :(得分:0)

您发送的用户名和密码为params

AFAIK Basic身份验证通过设置授权标头

来工作

使用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"]

请告诉我这是否适合您。