Обычная HTTP-аутентификация, не включающая JSON в заголовок?(Backbone.js на сервер Rails) - PullRequest
0 голосов
/ 16 декабря 2010

Я использую Backbone.js для создания чистого JS-интерфейса для моего приложения rails с использованием API-интерфейса JSON.

URL модели backbone.js выглядит следующим образом:

window.MedicationCollection = Backbone.Collection.extend({
  model: Medication,
    url: 'http://localhost:3000/medication_options'
});

CRUD отлично работает с этим. Он отправляет запросы на мой сервер с типом контента "application / JSON".

Но мне нужно было добавить аутентификацию для API, и мое приложение rails использует Authlogic, поэтому я добавил это:

  before_filter :require_user

     def require_http_auth_user
        return true if current_user
        authenticate_or_request_with_http_basic do |email, password|
          email = email.gsub("_at_", "@") if email.include?("_at_")
          if @current_user = User.find_by_email(email)
            @current_user.valid_password?(password)
          else
            false
          end
        end
      end

А типичный метод CRUD в рельсах выглядит так:

  def update
    @medication_option = MedicationOption.find(params[:id])
    if @medication_option.update_attributes(params[:medication_option])
      flash[:notice] = "Successfully updated medication."
    end
    respond_with @medication_option
  end

Итак, в моей модели Backbone.js я добавил «имя пользователя: пароль» в URL:

window.MedicationCollection = Backbone.Collection.extend({
  model: Medication,
    url: 'http://username:password@localhost:3000/medication_options'
});

Аутентификация отлично работает с соответствующими учетными данными, но по какой-то причине все запросы Backbone.js интерпретируются сервером Rails как HTML, а не как JSON.

По какой-то причине во время обычной HTTP-аутентификации заголовок JSON теряется в миксе.

Так что, если я добавлю «.json» в конец URL-адреса следующим образом:

window.MedicationCollection = Backbone.Collection.extend({
  model: Medication,
    url: 'http://username:password@localhost:3000/medication_options.json'
});

Я могу заставить работать основные запросы GET.

Но когда я делаю CRUD, он не работает, потому что он добавляет идентификатор в конец URL, поэтому он выдает ошибки:

ActionController::RoutingError (No route matches "/medication_options.json/41516")

Так что я не уверен, куда идти отсюда.

Ответы [ 3 ]

1 голос
/ 16 декабря 2010

Ваш .json всегда должен быть в конце URL, чтобы интерпретироваться как json:

/medication_options/41516.json

Вы можете отредактировать URL модели, а также URL коллекции, если необходимо поместить json в нужное место.

Корень проблемы в том, почему он не обрабатывается как json. Если вы используете рельсы 3, у вас есть:

respond_to :js 

или

respond_to :json

, чтобы соответствовать вашему response_with и убедиться, что ваш контроллер принимает этот тип формата (в противном случае rails вернет ошибку 406 по умолчанию)?

0 голосов
/ 21 апреля 2011

Попробуйте что-то вроде этого:

 _.extend(Medication, 
    {extension:'.json',
     url:function() {
          var base = getUrl(this.collection);
          if (this.isNew()) return base + this.extension;
          return (base + (base.charAt(base.length - 1) == '/' ? '' : '/')
                  + this.id + this.extension);
        }
    });
0 голосов
/ 16 декабря 2010

Я никогда не использовал Document.js, но при просмотре документов кажется, что вы можете переопределить url и вернуть результат функции вместо того, чтобы давать ей буквальное строковое значение.Не могли бы вы добавить .json в конец строки URL таким образом?

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...