• <ins id="pjuwb"></ins>
    <blockquote id="pjuwb"><pre id="pjuwb"></pre></blockquote>
    <noscript id="pjuwb"></noscript>
          <sup id="pjuwb"><pre id="pjuwb"></pre></sup>
            <dd id="pjuwb"></dd>
            <abbr id="pjuwb"></abbr>

            qiezi的學(xué)習(xí)園地

            AS/C/C++/D/Java/JS/Python/Ruby

              C++博客 :: 首頁 :: 新隨筆 ::  ::  :: 管理 ::
            一、前言

            出于數(shù)據(jù)安全性考慮,某些破壞性鏈接應(yīng)該使用post請(qǐng)求,比如一個(gè)刪除記錄的請(qǐng)求。

            除了腳本確認(rèn)以外,服務(wù)端還需要post驗(yàn)證,因?yàn)槟_本是可以繞過的。想像你的頁面上有一個(gè)刪除鏈接,只作了客戶端腳本確認(rèn)(老的scaffold生成代碼有這問題),被google找到了,它一個(gè)請(qǐng)求就會(huì)讓你的數(shù)據(jù)丟失。

            rails對(duì)于這類請(qǐng)求的處理,是通過verify方法,默認(rèn)的scaffold生成代碼有如下內(nèi)容:

            ??#?GETs?should?be?safe?(see?http://www.w3.org/2001/tag/doc/whenToUseGet.html)
            ??verify?:method?=>?:post,?:only?=>?[?:destroy,?:create,?:update?],
            ?????????
            :redirect_to?=>?{?:action?=>?:list?}

            只有post請(qǐng)求時(shí),destroy才會(huì)被允許,如果是get,就會(huì)被重定向到list。

            二、實(shí)現(xiàn)

            我自己實(shí)現(xiàn)了一個(gè)method_dispatch,當(dāng)請(qǐng)求一個(gè)/test/a時(shí),如果是get,則會(huì)直接執(zhí)行TestController#a;如果是post,則會(huì)執(zhí)行TestController#a_post,a_post應(yīng)該是protected,這樣不會(huì)直接暴露給客戶,get/post就嚴(yán)格區(qū)分開來了。

            method_dispatch現(xiàn)在是直接實(shí)現(xiàn)在ApplicationController中的,代碼如下:

            class?ApplicationController?<?ActionController::Base
            ??protected
            ??def?self
            .method_dispatch(*methods)
            ????before_filter?
            :do_method_dispatch,?:only?=>?methods.flatten.map(&:to_sym)
            ??end

            ??private
            ??def?do_method_dispatch
            ????
            if?request.post??&&?respond_to?("#{action_name}_post")
            ??????
            eval("#{action_name}_post")
            ??????
            return?false
            ????end
            ??end
            end

            由于ApplicationController里面的方法會(huì)被子類繼承到,所以必須嚴(yán)格處理訪問級(jí)別。

            使用如下:

            class?TestController?<?ApplicationController
            ??method_dispatch?
            :a

            ??def?
            index
            ??end

            ??def?a
            ????render?
            :text?=>?'get?a'
            ??end
            ??def?b
            ????render?
            :text?=>?'get?b'
            ??end
            ??protected
            ??def?a_post
            ????render?
            :text?=>?'post?a'
            ??end
            ??def?b_post
            ????render?
            :text?=>?'post?b'
            ??end
            end

            注意a_post,b_post要被保護(hù)起來防止直接調(diào)用。

            index.rhtml里面演示了使用get和post的情況:

            <%=?link_to?"Get?a",?:action?=>?'a'?%>
            <%=?link_to?"Post?a",?{:action?=>?'a'},?{:post?=>?true}?%><br?/>

            <%=?link_to?"Get?b",?:action?=>?'b'?%>
            <%=?link_to?"Post?b",?{:action?=>?'b'},?{:post?=>?true}?%><br?/>

            rails在處理有:post => true參數(shù)的link_to時(shí),生成的代碼如下:

            <a?href="/test/a"?onclick="var?f?=?document.createElement('form');
            ?????? this.parentNode.appendChild(f);?f.method?=?'POST';?f.action?=?this.href;?f.submit();return?false;"
            >Post?a</a>

            經(jīng)測(cè)試上面代碼工作情況良好,使用get訪問/test/a時(shí),顯示get a;使用post訪問時(shí),顯示post a。使用get訪問/test/b時(shí),顯示get b;使用post時(shí),顯示get b,因?yàn)閎并沒有使用method_dispatch。

            三、應(yīng)用

            下面的posts_controller.rb是scaffold生成的:

            class?PostsController?<?ApplicationController
            ??def?
            index
            ????list
            ????render?
            :action?=>?'list'
            ??end

            ??
            #?GETs?should?be?safe?(see?http://www.w3.org/2001/tag/doc/whenToUseGet.html)
            ??verify?:method?=>?:post,?:only?=>?[?:destroy,?:create,?:update?],
            ?????????
            :redirect_to?=>?{?:action?=>?:list?}

            ??def?list
            ????
            @post_pages,?@posts?=?paginate?:posts,?:per_page?=>?10
            ??end

            ??def?show
            ????
            @post?=?Post.find(params[:id])
            ??end

            ??def?new
            ????
            @post?=?Post.new
            ??end

            ??def?create
            ????
            @post?=?Post.new(params[:post])
            ????
            if?@post.save
            ??????flash[
            :notice]?=?'Post?was?successfully?created.'
            ??????redirect_to?
            :action?=>?'list'
            ????
            else
            ??????render?
            :action?=>?'new'
            ????end
            ??end

            ??def?edit
            ????
            @post?=?Post.find(params[:id])
            ??end

            ??def?update
            ????
            @post?=?Post.find(params[:id])
            ????
            if?@post.update_attributes(params[:post])
            ??????flash[
            :notice]?=?'Post?was?successfully?updated.'
            ??????redirect_to?
            :action?=>?'show',?:id?=>?@post
            ????
            else
            ??????render?
            :action?=>?'edit'
            ????end
            ??end

            ??def?destroy
            ????Post
            .find(params[:id]).destroy
            ????redirect_to?
            :action?=>?'list'
            ??end
            end

            可以看到,它添加了verify,但action過多,需要在verify中維護(hù)一份對(duì)應(yīng)方法名,稍不留神就容易出現(xiàn)漏洞。

            我把它修改如下:

            class?PostsController?<?ApplicationController
            ??method_dispatch?
            :new,?:edit,?:destroy

            ??def?
            index
            ????list
            ????render?
            :action?=>?'list'
            ??end

            ??def?list
            ????
            @post_pages,?@posts?=?paginate?:posts,?:per_page?=>?10
            ??end

            ??def?show
            ????
            @post?=?Post.find(params[:id])
            ??end

            ??def?new
            ????
            @post?=?Post.new
            ??end

            ??def?edit
            ????
            @post?=?Post.find(params[:id])
            ??end

            ??def?destroy
            ????render?
            :inline?=>?<<-EOS
            ????? Are you sure?
            ??????
            <%=?link_to?"Yes",?{},?:post?=>?true?%>
            ??????
            <%=?link_to?"No",?:action?=>?'edit', :id => params[:id]%>
            ????EOS
            ??end

            ??protected
            ??def?destroy_post
            ????Post
            .find(params[:id]).destroy
            ????redirect_to?
            :action?=>?'list'
            ??end
            ??def?edit_post
            ????
            @post?=?Post.find(params[:id])
            ????
            if?@post.update_attributes(params[:post])
            ??????flash[
            :notice]?=?'Post?was?successfully?updated.'
            ??????redirect_to?
            :action?=>?'show',?:id?=>?@post
            ????
            else
            ??????render?
            :action?=>?'edit'
            ????end
            ??end
            ??def?new_post
            ????
            @post?=?Post.new(params[:post])
            ????
            if?@post.save
            ??????flash[
            :notice]?=?'Post?was?successfully?created.'
            ??????redirect_to?
            :action?=>?'list'
            ????
            else
            ??????render?
            :action?=>?'new'
            ????end
            ??end
            end

            相應(yīng)地,還需要把new.rhtml中的action從create修改到new,把edit.rhtml中的action從update修改到edit。

            這樣的修改把必須使用post請(qǐng)求的action隱藏起來,而相應(yīng)的get操作是不修改或刪除記錄的,如果以post請(qǐng)求,才會(huì)自動(dòng)調(diào)用這些保護(hù)的方法。
            posted on 2006-09-17 11:13 qiezi 閱讀(768) 評(píng)論(3)  編輯 收藏 引用 所屬分類: Ruby
            亚洲精品无码久久久久AV麻豆| 人妻无码精品久久亚瑟影视 | 久久久久无码精品国产app| 国产精品青草久久久久福利99| 四虎影视久久久免费观看| 婷婷伊人久久大香线蕉AV| 国产一区二区三区久久精品| 国产精品女同一区二区久久| 久久人人爽人人爽人人片AV不| 国产一区二区精品久久| 久久精品视频一| 久久精品女人天堂AV麻| 国产精品久久久久AV福利动漫| 久久久久99精品成人片牛牛影视| 午夜精品久久久久久中宇| 久久精品这里只有精99品| 97r久久精品国产99国产精| 午夜精品久久久久久影视riav| 久久777国产线看观看精品| 久久人人爽人人爽人人片AV东京热| 国内精品久久久久国产盗摄| 久久精品国产第一区二区三区| 青青草国产97免久久费观看| 91亚洲国产成人久久精品| 久久国产精品99精品国产| 久久久久久久精品妇女99| 亚洲精品NV久久久久久久久久| 四虎国产永久免费久久| 久久婷婷五月综合97色| 99久久99久久精品国产片果冻| 热RE99久久精品国产66热| 久久久久99精品成人片牛牛影视| 热久久这里只有精品| 91秦先生久久久久久久| 久久se精品一区精品二区| 国内精品久久久久久野外| 久久99精品久久久久婷婷| 国产精品女同久久久久电影院| 国内精品伊人久久久久av一坑| 久久久精品人妻一区二区三区四| 色婷婷久久综合中文久久蜜桃av|