2017-03-08 14 views
2

我有一個用python/flask寫的API,我想只允許幾個URL訪問這個API。 JavaScript調用是微不足道的jQuery,如:針對多個URL的Flask訪問控制允許來源地址

$.ajax({ 
    url: "http://myApi.com/api/doit", 
    dataType:'JSON', 
    success:function(data){ 
     console.log("DEBUG: yeeeeaaaahhh!"); 
    }, 
    error:function(xhr){ 
     console.log("Error occured! status: " + xhr.status + ", text: " + xhr.statusText); 
    } 
    }); 

大部分的解決方案,主要是這裏都是相當令人失望總是提供設置Access-Control-Allow-Origin : '*'或啓動鉻禁用檢查。當然它有效,但這不是目的。 關於w3的規範說分號分隔的列表應該可以工作,但它不會。也逗號分隔列表失敗。 從燒瓶本身有http://flask.pocoo.org/snippets/56/,但它不適用於多個URL。在評論中有一個建議:h.extend([("Access-Control-Allow-Origin", orig) for orig in origin])但它仍然無法正常工作。

我唯一的解決方案是檢查代碼的來源,如果它在我的白名單上,在標題Access-Control-Allow-Origin : '*'。這是一種解決方法,但我不太喜歡它。你能建議一個更優雅的解決方案嗎?

回答

2

這是在本地使用同一個前端項目的多個實例一起訪問本地Flask服務器並且由於您允許憑據(即使用JWT身份驗證)而不允許通配符「*」時的典型場景。

我的方法 - 在開發中 - 是使用裝飾器和Flask的請求上下文after_request

創建一個域白名單:

white = ['http://localhost:8080','http://localhost:9000'] 

現在使用after_request裝飾攔截所有的請求,檢查是否引用是在你的白名單,如果是,注入response.headers允許訪問的由來。例如:

from flask import request 

@app.after_request 
def add_cors_headers(response): 
    r = request.referrer[:-1] 
    if r in white: 
     response.headers.add('Access-Control-Allow-Origin', r) 
     response.headers.add('Access-Control-Allow-Credentials', 'true') 
     response.headers.add('Access-Control-Allow-Headers', 'Content-Type') 
     response.headers.add('Access-Control-Allow-Headers', 'Cache-Control') 
     response.headers.add('Access-Control-Allow-Headers', 'X-Requested-With') 
     response.headers.add('Access-Control-Allow-Headers', 'Authorization') 
     response.headers.add('Access-Control-Allow-Methods', 'GET, POST, OPTIONS, PUT, DELETE') 
    return response