2017-05-09 96 views
0

我有一個使用graphene-django實現的graphql服務器。我可以使用jquery這樣進行查詢到它:Django在POST請求上返回403錯誤,提取

function allIngredients() { 
    return 'query{allProducts{edges{node{name}}}}' 
    } 
    var query = allIngredients(); 
    $.ajaxSetup({ 
    data: {csrfmiddlewaretoken: '{{ csrf_token }}' }, 
    }); 
    $.post("/graphql", {query: query}, function(response) { 
    console.log(response); 
    }) 

然而,當我嘗試此調用與取,我得到一個403,因爲CORS問題。我通過在調用之前添加ajaxSetup ...來解決jQuery中的相同問題。

下面是一個使用獲取的呼叫:

fetch('/graphql', { 
     method: "POST", 
     headers: { 
      'Content-Type': 'application/json' 
     }, 
     credentials: 'include', 
     body: JSON.stringify({ 
      csrfmiddlewaretoken: '{{ csrf_token }}', 
      query:`{allProducts{ 
      edges{ 
       node{ 
       id 
       name 
       orderPrice 
       sellPrice 
       } 
      } 
      }`}) 
     } 
    ) 
    .then(function(response) { 
     if (response.status >= 400) { 
      throw new Error("Bad response from server"); 
     } 
     return response.json(); 
    }) 

我嘗試添加csrfmiddlewaretoken到身在類似的方式,我在jQuery的例子一樣,沒有運氣。我嘗試添加憑據:'包含'爲the docs say,再次沒有運氣。我嘗試了憑據:「同源」,並將這些選項以不同的方式組合,再次得到相同的結果。網站對此非常安靜,我做錯了什麼?

回答

0

該解決方案在getCookie()方法中。

fetch("/graphql", { 
     method: "POST", 
     credentials: "same-origin", 
     headers: { 
      "X-CSRFToken": getCookie("csrftoken"), 
      "Accept": "application/json", 
      'Content-Type': 'application/json' 
     }, 
     body:JSON.stringify(query) 
     }) 

當然,該方法必須在同一頁上。從Django Docs.

function getCookie(name) { 
    var cookieValue = null; 
    if (document.cookie && document.cookie !== '') { 
     var cookies = document.cookie.split(';'); 
     for (var i = 0; i < cookies.length; i++) { 
      var cookie = jQuery.trim(cookies[i]); 
      // Does this cookie string begin with the name we want? 
      if (cookie.substring(0, name.length + 1) === (name + '=')) { 
       cookieValue = decodeURIComponent(cookie.substring(name.length + 1)); 
       break; 
      } 
     } 
    } 
    return cookieValue; 
} 
2

採取如果你想使該職位的要求形成不同的域(在情況下,當應用程序的前面是反應或角和後端是在Django),請確保以下附加設置文件:

  1. 更新INSTALLED_APPS使用 'coreHeaders':

    INSTALLED_APPS = [
    'corsheaders',
    ]

  2. 白名單中加入以下內容設置您的前端域再次文件:

    CORS_ORIGIN_WHITELIST =( 的 'localhost:8080', )

現在允許允許任何人發佈此帖子請求:

注意:應該在您不需要認證用戶在我們的服務器上發佈任何內容的情況下使用,例如,當新用戶首次註冊時

from rest_framework.permissions import AllowAny 

class CreateUser(APIView): 
    permission_classes = (AllowAny,) 
    def post(self, request, format=None): 
     return(Response("hi"))