Основная HTTP -аутентификация не включая JSON в заголовке? (Backbone.js на сервер Rails)
-
11-10-2019 - |
Вопрос
Я использую Backbone.js, чтобы создать интерфейс Pure JS для моего приложения Rails, используя API JSON.
URL модели Backbone.js выглядит так:
window.MedicationCollection = Backbone.Collection.extend({
model: Medication,
url: 'http://localhost:3000/medication_options'
});
Круд отлично работает с этим. Он отправляет запросы на мой сервер с типом контента «Приложение/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 в Rails выглядит так:
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'
});
Я могу получить базовые запросы на работу.
Но когда я делаю Crud, это не работает, потому что он добавляет идентификатор к концу URL, так что это ошибки:
ActionController::RoutingError (No route matches "/medication_options.json/41516")
Так что я не уверен, куда идти отсюда.
Решение
Ваш .json всегда должен быть в конце URL -адреса, который будет интерпретироваться как JSON:
/medication_options/41516.json
Вы можете редактировать URL -адрес модели, а также URL -адрес коллекции, если это необходимо, чтобы поставить JSON в нужном месте.
Корневая проблема заключается в том, почему он не обрабатывается как JSON в первую очередь. Если вы используете Rails 3, у вас есть:
respond_to :js
или же
respond_to :json
Чтобы соответствовать вашему ответу и убедиться, что ваш контроллер принимает этот вид формата (в противном случае Rails вернет 406 ошибку по умолчанию)?
Другие советы
Я никогда не использовал Document.js, но, просматривая документы, кажется, вы можете переопределить url
и вернуть результат функции вместо того, чтобы придать ей буквальное строковое значение. Не могли бы вы добавить .json
до конца строки URL таким образом?
Попробуйте что -то вроде этого:
_.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);
}
});