2013-08-26 75 views
10

我有一個用作REST API後端的應用程序。我想爲後端實現基於令牌的身份驗證,但爲了做到這一點,我需要檢索用戶令牌。 Flask-Security文檔明確指出,爲了檢索令牌,需要執行HTTP POST並將認證詳細信息作爲JSON數據發送到認證端點。不幸的是,我不明白如何檢索執行此請求所需的CSRF令牌。Flask-Security CSRF令牌

如果我使用隨擴展一起提供的登錄頁面/模板,則CSRF令牌在窗體的隱藏字段中傳遞給客戶端。問題是:

如何在不訪問和解析登錄頁面的情況下檢索CSRF令牌,例如使用$ http方法或移動應用程序從angularJS應用中獲取樣例?

很顯然,我可以避免使用Flask-Security並自己實現這些部分,但是我對webapps相對缺乏經驗,我覺得我可能會以錯誤的方式接近它。

+0

你是如何做到這一點的? – kyrre

+0

我最終自己實現了安全層。對不起,我沒有更好的答案給你。 – Jacopo

+0

請注意,沒有安全的方式將標記存儲在angularjs中,請參閱[這裏](https://stormpath.com/blog/where-to-store-your-jwts-cookies-vs-html5-web-storage/)。安全選項是讓服務器將令牌存儲在僅限http的cookie中並啓用CSRF保護。如果你需要談論的是angularjs,那麼你可以使用session(+ anti-CSRF)。 – Adversus

回答

2

我還沒有測試過這個功能,但是從簡要檢查source code看來,您必須向內容類型設置爲application/json的登錄URL發送GET請求。 Flask-Security使用JSON版本的登錄表單響應此請求,幷包含令牌。一旦你有令牌,你可以發送POST請求。

+0

謝謝你穿上正確的道路。在創建GET請求之前,我必須傳遞一些json數據,否則'請求.json'在Flask中爲空,'_render_json'方法不會被觸發。不幸的是,雖然這會導致鏈接源45行上的錯誤,因爲表單沒有用戶屬性。但是簡單地看一下代碼,我認爲應該在驗證期間設置用戶屬性,但對於這個請求不會發生。我將不得不繼續挖掘。再次感謝 – Jacopo

+0

好吧,我想出了錯誤。 Flask-WTF的'validate_on_submit'方法首先檢查'is_submitted',GET請求爲false。這樣可以防止調用「validate」方法,並阻止分配表單中的「user」屬性。然而,手動調用'validate'方法會產生'CSRF令牌缺失'錯誤,我們又回到了一開始。 – Jacopo

4

我也有類似的用例和結束按照從燒瓶WTF文件這個例子中解決它:https://flask-wtf.readthedocs.org/en/latest/csrf.html#ajax

因此,通過CSRF通過CsrfProtect(app)保護應用程序,該csrf_token()成爲所有模板可用。然後你就可以很容易地通過腳本標籤可用它:

<script type="text/javascript"> 
    var csrftoken = "{{ csrf_token() }}" 
</script> 

現在添加標記到您的文章數據的燒瓶安全/登錄端點。

+2

感謝您的答案,但我最終實現了我自己的用戶管理解決方案。此外,這隻適用於如果您使用Flask應用程序提供頁面並且您使用Jinja呈現模板的情況。如果您僅將Flask應用程序用於後端(REST API),並且前端與其他方法一起提供,則必須提供API端點來檢索令牌並將其呈現在json響應中。我不確定這是如何工作的,也許我會試一試。 – Jacopo

0

[寫作作爲一個答案,因爲我沒有足夠的信譽發表評論]

我遇到了完全一樣的問題,雅格布在 - request.json是空的,因此get_auth_token()不會被觸發。

BTW - Flask Security documentation說:基於

令牌認證是通過與認證信息作爲對身份驗證端點的JSON數據執行HTTP POST檢索用戶的身份驗證令牌啓用。

所以,我想POST,無法獲得(空request.json的還是同樣的問題) 我打電話使用JSON數據/登錄:

{"email": "[email protected]", "password": "test123"} 

和發送谷歌瀏覽器使用郵差客戶端的請求。

然而,request.json是空的:(

編輯:我能夠繼續前進使用Python的請求模塊詳細here

+0

嗨Mandar,我希望你解決了這個問題,但我只是發佈了一個答案,可能會有所幫助:http://stackoverflow.com/a/27926284/992509 – SJoshi

+1

您在您的博文中給出的答案是startquestion(如何實現在使用json登錄到flask-security時使用csrf標記)本質上是:在flask-security的配置中禁用csrf認證。這是保存嗎?根據這篇文章(https://auth0.com/blog/2014/01/07/angularjs-authentication-with-cookies-vs-token/),只要你不使用cookies: 「 CSRF:因爲你不依賴於cookies,所以你不需要防止跨站點請求......「但是它真的和使用csrf令牌一樣節省了嗎? – Sebastian

1

昨晚我這個問題爭取了時間。以下是最終爲我工作:

當我創建我的應用程序實例:

app = Flask(__name__) 
app.config.from_object(config_by_name[config_name]) 

# Create database connection object 
app.db = db 
app.db.init_app(app) 

CsrfProtect(app) 

在我/登錄HTML:

<meta name="csrf-token" content="{{ csrf_token() }}"> 

從郵差:

enter image description here

這是我嘗試的另一種選擇,也許這會更成功?這是基本相同的答覆,該瓶的安全性例子應用給出:

enter image description here

2

那麼,有一個簡單的方法。 Visit。配置項目WTF_CSRF_ENABLED可以設置爲False以禁用csrf。然後,一切都如你所願。

+1

這解決了我的問題,謝謝。它可能因爲它禁用了安全功能而被降低了。但是,如果REST服務器只進行令牌認證而不是基於cookie的認證,則CSRF令牌是多餘的。 (我歡迎所有關於此的評論!) – velotron