为什么销毁操作会在 Rails 3 中触发生产中的 HTTP 身份验证? [英] Why does destroy action trigger HTTP authentication in Production in Rails 3?

查看:32
本文介绍了为什么销毁操作会在 Rails 3 中触发生产中的 HTTP 身份验证?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

按删除"时发生的情况的屏幕截图:http://twitpic.com/4mljuy

这是我在 production.log 中看到的:

在 2011-04-20 13:48:26 -0500 开始为 127.0.0.1 POST "/clients/1"由 ClientsController#destroy 处理为 JSON参数:{"id"=>"1"}零3ms内完成

这是我在控制器中的销毁操作:

def 销毁客户端 = Client.find(params[:id])client.destroyresponse_to do |格式|format.html { redirect_to("/") }format.js { 渲染:json =>['client',params[:id]].to_json, :layout =>错误的 }结尾结尾

这是我认为的删除链接:

</span>

这是JS:

$('[data-destroy-url]').live('click', function(e){console.debug("点击销毁");var 元素 = $(this);var mapping = compv.tools.getVariableFromString(element.attr("data-compv-mapping"), compv);var dialog = $("div#" + mapping.dialog);dialog.dialog('option', 'title', element.attr("data-destroy-title"));dialog.dialog("选项",纽扣", [{ 文字:不",点击:函数(){dialog.dialog('关闭');}},{文字:是的,做吧!",点击:函数(){dialog.dialog('关闭');$.destroy({url: element.attr('data-destroy-url'),成功:mapping.success});}}]);dialog.dialog('打开');});

顺便说一句,这只发生在 RAILS_ENV=production 而不是 development 时.

这是我的应用程序控制器:

class ApplicationController <动作控制器::基础帮手:全部helper_method :current_user, :logged_in?保护免受伪造before_filter :set_current_userbefore_filter :authenticate_user!def set_xhr_flashflash.discard if request.xhr?结尾def right_safari_and_ie_accept_headersajax_request_types = ['text/javascript', 'application/json', 'text/xml']请求.接受.排序!{ |x, y|ajax_request_types.include?(y.to_s) ?1 : -1 } 如果 request.xhr?结尾受保护def set_current_userlogger.info current_user.inspectAuthorization.current_user = current_user#User.current = current_user结尾# def after_sign_in_path_for(资源)# if resource.is_a?(User) &&resource.has_trial_expired?# 返回 url_for(:settings)#       结尾#       极好的#   结尾结尾

Edit2:当我试图删除一个阶段(它是一个对象)时,我在我的日志文件中收到了这条消息:

在 2011-04-20 23:18:13 -0500 开始为 127.0.0.1 POST "/stages/58"由 StagesController#destroy 处理为 JSON参数:{"id"="58"}用户负载 (1.6ms) SELECT "users".* FROM "users" WHERE "users"."id" = 11 LIMIT 1零权限被拒绝:没有找到用于销毁的匹配规则 #(角色 [:guest]、权限 [:destroy]、上下文 :stages).渲染文本模板(0.0ms)在 232ms 内完成 403 Forbidden (Views: 0.9ms | ActiveRecord: 1.6ms)

解决方案

更新到最新的 jquery ujs 驱动程序,其中在每个请求中包含 CSRF 令牌,以防止您的会话自 3.0.4 中的变化.

Screenshot of what happens when I press 'delete': http://twitpic.com/4mljuy

This is what I see in my production.log:

Started POST "/clients/1" for 127.0.0.1 at 2011-04-20 13:48:26 -0500
  Processing by ClientsController#destroy as JSON
  Parameters: {"id"=>"1"}
nil
Completed   in 3ms

This is my destroy action in my controller:

def destroy
     client = Client.find(params[:id])
     client.destroy
     respond_to do |format|
        format.html { redirect_to("/") }
        format.js   { render :json => ['client',params[:id]].to_json, :layout => false }
    end
end

This is the delete link in my view:

<span class="icon destroy-icon" data-destroy-title="Delete <%= client.email %>?" data-destroy-url="<%= client_path(client) %>" data-compv-mapping="clientDestroyFn" title="Delete"> </span>

Here is the JS:

$('[data-destroy-url]').live('click', function(e){
    console.debug("Clicked Destroy");
    var element = $(this);
    var mapping = compv.tools.getVariableFromString(element.attr("data-compv-mapping"), compv);
    var dialog = $("div#" + mapping.dialog);
    dialog.dialog('option', 'title', element.attr("data-destroy-title"));
    dialog.dialog("option", 
        "buttons", [
        { text: "No",
          click: function(){
            dialog.dialog('close');
        }
        },
    { text: "Yes, do it!",
      click: function() {
        dialog.dialog('close');
        $.destroy({
            url: element.attr('data-destroy-url'),
            success: mapping.success
        });
    }}
    ]);
    dialog.dialog('open');
});

Btw, this only happens when RAILS_ENV=production and not development.

Edit: Here is my application controller:

class ApplicationController < ActionController::Base
  helper :all
  helper_method :current_user, :logged_in?

  protect_from_forgery
  before_filter :set_current_user
  before_filter :authenticate_user!

  def set_xhr_flash
    flash.discard if request.xhr?
  end

  def correct_safari_and_ie_accept_headers
    ajax_request_types = ['text/javascript', 'application/json', 'text/xml']
    request.accepts.sort! { |x, y| ajax_request_types.include?(y.to_s) ? 1 : -1 } if request.xhr?
  end

  protected 

  def set_current_user
    logger.info current_user.inspect
    Authorization.current_user = current_user
    #User.current = current_user
  end

    # def after_sign_in_path_for(resource)
    #       if resource.is_a?(User) && resource.has_trial_expired?
    #           return url_for(:settings)
    #       end
    #       super       
    #   end

end

Edit2: When I tried to delete a stage (which is an object), I got this message in my log file:

Started POST "/stages/58" for 127.0.0.1 at 2011-04-20 23:18:13 -0500
  Processing by StagesController#destroy as JSON
  Parameters: {"id"=>"58"}
  User Load (1.6ms)  SELECT "users".* FROM "users" WHERE "users"."id" = 11 LIMIT 1
nil
Permission denied: No matching rules found for destroy for #<Authorization::AnonymousUser:0x000001052659c0 @role_symbols=[:guest]> (roles [:guest], privileges [:destroy], context :stages).
Rendered text template (0.0ms)
Completed 403 Forbidden in 232ms (Views: 0.9ms | ActiveRecord: 1.6ms)

解决方案

Update to the latest jquery ujs driver which includes the CSRF token in each request to prevent your session from being reset since the changes in 3.0.4.

这篇关于为什么销毁操作会在 Rails 3 中触发生产中的 HTTP 身份验证?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆