vue+django前后端分析解決csrf token問題


vue-resource post數據

參考:https://www.cnblogs.com/linxizhifeng/p/8995077.html

閱讀django CsrfViewMiddleware源碼可知,csrftoken可以放在請求參數(csrfmiddlewaretoken)里面或者請求頭(X-CSRFToken)里:

     # Check non-cookie token for match.
            request_csrf_token = ""
            if request.method == "POST":
                try:
                    request_csrf_token = request.POST.get('csrfmiddlewaretoken', '')
                except IOError:
                    # Handle a broken connection before we've completed reading
                    # the POST data. process_view shouldn't raise any
                    # exceptions, so we'll ignore and serve the user a 403
                    # (assuming they're still listening, which they probably
                    # aren't because of the error).
                    pass

            if request_csrf_token == "":
                # Fall back to X-CSRFToken, to make things easier for AJAX,
                # and possible for PUT/DELETE.
                request_csrf_token = request.META.get(settings.CSRF_HEADER_NAME, '')    

 

1 this.$http.post('/someUrl',data, [options]).then(function(response){
2     // 響應成功回調
3 }, function(response){
4     // 響應錯誤回調
5 });

vue-resource 向后端請求api, 公司的后台是用Django 開發的,Django為了防止跨站請求偽造,即csrf攻擊,提供了CsrfViewMiddleware中間件來防御csrf攻擊。

我們在html 頁面里加入{% csrf %}來讓django渲染出一個csrf的標簽 
(如果是form 提交表單的話,我們要把這個標簽加在form標簽內,如果是用xhr提交的話寫在html頁面里就可以了)

手動生成csrftoken

1。request.META["CSRF_COOKIE_USED"] = True
2。手動調用 csrf 中的 get_token(request) 或 rotate_token(request) 方法
3。html表單帶{%csrf_token%} (適用於django render渲染的前端)

4。裝飾器ensure_csrf_cookie

不寫在form 表單內,但是實現效果是一樣的,我們都需要在post 的表單中提供csrftoken我們在vue里要傳送的的data 里要加上csrf的key

data{
    csrfmiddlewaretoken: '{{ csrf_token }}' 
}

 

這樣django解析表單時會解析到csrf_token, 我們post的數據就不會遇到403 forbidden了。

其實這樣是投機取巧的行為,這樣雖然django 也能識別,但是遇到復雜的數據時就不行了,比如數組,vue-resource post 數組的時候, 因為我之前在post的option里加了一個option {emulateJSON: true},這樣vue-resource 在post數據時,會把data 轉換成 application/x-www-form-urlencoded表單格式,但是這樣的話,post 的數組就會被解析成arrry[0]item 這樣的話,后端是不識別的,會報錯。

解決方式查到是把csrftoken 放在報頭里,data 傳數據,具體解決方式是加一條

Vue.http.headers.common['X-CSRFToken'] = $("input[name='csrfmiddlewaretoken']").val()

其中$("input[name='csrfmiddlewaretoken']").val() 是取django 的{% csrf %}在模板解析后生成的input里的csrftoken。

其中報頭的話django 在后台解析的時候會自動加上HTTP_的前綴,所以說我們的報頭是 X-CSRFToken就可以了。

 

另附一片參考博客地址:https://www.cnblogs.com/linxizhifeng/p/8995077.html

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM