基本 HTTP 身份验证在标头中不包含 JSON? (Backbone.js 到 Rails 服务器)
我正在使用 Backbone.js 使用 JSON api 为我的 Rails 应用程序创建纯 JS 前端。
backbone.js 模型 URL 如下所示:
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
Rails 中典型的 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'
});
使用适当的凭据,身份验证可以正常工作,但由于某种原因,Rails 服务器将所有 Backbone.js 请求解释为 HTML 而不是 JSON。
由于某种原因,在基本 HTTP 身份验证过程中,JSON 标头会在混合中丢失。
因此,如果我像这样显式地将“.json”添加到 URL 末尾:
window.MedicationCollection = Backbone.Collection.extend({
model: Medication,
url: 'http://username:password@localhost:3000/medication_options.json'
});
我可以获得基本的 GET 请求。
但是当我执行 CRUD 时,它不起作用,因为它将 ID 附加到 URL 的末尾,所以它会出错:
ActionController::RoutingError (No route matches "/medication_options.json/41516")
所以我不确定从这里去哪里。
I'm using Backbone.js to create a pure JS front-end for my rails app using a JSON api.
The backbone.js model URL looks like this:
window.MedicationCollection = Backbone.Collection.extend({
model: Medication,
url: 'http://localhost:3000/medication_options'
});
CRUD works fine with this. It's sending requests to my server with an "application/JSON" content type.
But I needed to add authentication for the API and my rails app is using Authlogic so I added this:
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
And a typical CRUD method in rails looks like this:
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
So in my Backbone.js model I added "username:password" to the url:
window.MedicationCollection = Backbone.Collection.extend({
model: Medication,
url: 'http://username:password@localhost:3000/medication_options'
});
The authentication works fine with the appropriate credentials, but for some reason all of the Backbone.js requests are interpreted by the Rails server as HTML instead of JSON.
For some reason during an Basic HTTP authentication, the JSON header gets lost in the mix.
So if I explicitly add ".json" to the end of the URL like this:
window.MedicationCollection = Backbone.Collection.extend({
model: Medication,
url: 'http://username:password@localhost:3000/medication_options.json'
});
I can get basic GET requests to work.
But when I do CRUD it doesn't work because it appends the ID to the end of the URL, so it errors:
ActionController::RoutingError (No route matches "/medication_options.json/41516")
So I'm not sure where to go from here.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
您的 .json 应始终位于 url 的末尾以被解释为 json:
如果需要将 json 放在正确的位置,您可以编辑模型 url 以及集合 URL。
根本问题是为什么它首先没有被处理为 json。如果您使用的是rails 3,您是否有:
或
匹配您的respond_with并确保您的控制器接受这种格式(否则rails默认会返回406错误)?
Your .json should always be at the end of the url to be interpreted as json:
You can edit the Model url as well as the collection URL if needed to put the json at the right place.
The root problem is why it doesn't get processed as json in the first place. If you are using rails 3 do you have:
or
to match your respond_with and make sure your controller accepts this kind of format (otherwise rails would return 406 error by default)?
我从未使用过 Document.js,但在查看文档时,您似乎可以覆盖
url
并返回函数的结果,而不是为其提供文字字符串值。您可以通过这种方式将.json
添加到 url 字符串的末尾吗?I've never used Document.js, but in looking through the docs it seems you can override
url
and return the result of a function instead of giving it a literal string value. Could you add the.json
to the end of the url string that way?尝试这样的事情:
Try something like this: