vue+django先後端分析解決csrf token問題

vue-resource post數據

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

閱讀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攻擊。vue

咱們在html 頁面里加入{% csrf %}來讓django渲染出一個csrf的標籤 
(若是是form 提交表單的話,咱們要把這個標籤加在form標籤內,若是是用xhr提交的話寫在html頁面裏就能夠了)django

手動生成csrftoken後端

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

4。裝飾器ensure_csrf_cookie數組

不寫在form 表單內,可是實現效果是同樣的,咱們都須要在post 的表單中提供csrftoken咱們在vue裏要傳送的的data 裏要加上csrf的keycookie

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

 

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

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

解決方式查到是把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

相關文章
相關標籤/搜索