2013-08-26 26 views
10

私はREST APIバックエンドとして機能するフラスコアプリを持っています。バックエンドに対してトークンベースの認証を実装したいのですが、そのためにはユーザートークンを取得する必要があります。 Flask-Securityのドキュメントによれば、トークンを取得するには、認証の詳細をJSONデータとしてHTTPエンドポイントに送信する必要があります。残念ながら、私はそのような要求を実行するために必要なCSRFトークンを取得する方法を理解していません。Flask-Security CSRFトークン

拡張子が付いたログインページ/テンプレートを使用すると、フォームの非表示フィールドのクライアントにCSRFトークンが渡されます。問題は次のとおりです。

$ httpメソッドやモバイルアプリケーションを使用しているangelJSアプリケーションなどのように、ログインページにアクセスして解析することなくCSRFトークンを取得するにはどうすればよいですか?

明らかに私はFlask-Securityの使用を避け、自分自身で実装することができましたが、私はwebappsで比較的経験がなく、私はこれが間違った方法に近づいていると感じています。

+0

これはどのようにして終了しましたか? – kyrre

+0

私はセキュリティ層を自分で実装しました。申し訳ありませんがあなたのために良い答えがありません。 – Jacopo

+0

anglejsにトークンを格納する安全な方法はありません。 [ここ](https://stormpath.com/blog/where-to-store-your-jwts-cookies-vs-html5-web-storage/)。セキュアなオプションは、サーバーにトークンをhttp専用クッキーに格納させ、CSRF保護を有効にすることです。あなたが話す必要があるのはangularjsだけであれば、セッション(+ anti-CSRF)を使うこともできます。 – Adversus

答えて

2

これは動作しませんが、に設定されたコンテンツタイプのログインURLにGETリクエストを送信する必要があると思われます。 Flask-Securityはこのリクエストに、ログインフォームのJSONバージョンで応答し、トークンを含みます。トークンを取得すると、POST要求を送信できます。

+0

正しい道をつけてくれてありがとう。 GETリクエストを作成する上で、リクエストとともにjsonデータを渡す必要があります。そうでないと、 'request.json'はFlaskでは空であり、 '_render_json'メソッドはトリガーされません。残念ながら、フォームにはユーザー属性がないため、リンクしたソースの45行目でエラーが発生します。しかし、簡単にコードを見れば、ユーザー属性は検証中に設定する必要があると思いますが、この要求に対しては発生しません。私は掘り続けなければならない。再度ありがとう – Jacopo

+0

OK私はエラーを理解しました。 Flask-WTFの 'validate_on_submit'メソッドは、まず 'is_submitted'をチェックします。これはGET要求に対しては偽です。これにより、 'validate'メソッドが呼び出されず、フォームの 'user'属性が割り当てられなくなります。しかし、 'validate'メソッドを手動で呼び出すと、 'CSRF token missing'エラーが発生し、最初に戻ります。 – 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でテンプレートをレンダリングする場合にのみ機能します。あなたがバックエンド(REST API)のためのFlaskアプリケーションを使用し、フロントエンドが他の方法で提供される場合は、トークンを取得し、それをjsonレスポンスでレンダリングするAPIエンドポイントを提供する必要があります。どのようにこれが動作するか分からない、私は多分それを試してみましょう。 – Jacopo

0

[私がコメントするのに十分な評判を持っていないので、答えとして書く]

私はその中で、ヤコポとまったく同じ問題に遭遇してきた - request.jsonは空のため、get_auth_tokenである()がトリガされていません。ところで

からFlask Security documentationは述べています:

トークンベースの認証は、認証エンドポイントに対するJSONデータとして認証の詳細はHTTPのPOSTを実行することにより、ユーザ認証トークンを取得することで有効になります。

だから私は、私のようにJSONデータを/ログインを呼ば (空request.jsonのまだ同じ問題を)GETない、POSTを試してみました:

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

とGoogle Chromeでポストマンクライアントを使用して要求を送信し。しかし

、request.jsonが空である:(

編集:私は、Pythonの要求モジュールを使用して前進することができました詳細here

+0

こんにちはマンダール、私はあなたがこれを解決したいと思いますが、私はちょうど助けるかもしれない答えを投稿しました:http://stackoverflow.com/a/27926284/992509 – SJoshi

+1

あなたのblogpostにstartquestionで与えている答えフラスコセキュリティでjsonログインを使用する場合のcsrfトークン)は本質的にフラスコセキュリティの設定でcsrf認証を無効にします。これは保存されていますか?この[記事](https://auth0.com/blog/2014/01/07/angularjs-authentication-with-cookies-vs-token/)によると、Cookieを使用しない限り、 " CSRF:あなたがクッキーに頼っているわけではないので、クロスサイトリクエストから保護する必要はありません... "しかし、実際にはcsrfトークンを使用するのと同じくらい保存できますか? – Sebastian

1

私は昨夜時間この問題と戦いました。ここでは私のために働くことになったものです:

私は私のアプリのインスタンスを作成する場合:

私の/ログインHTMLで
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) 

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

郵便集配人から:

enter image description here

私はこれを試してみましたが、これはもっと成功するでしょうか?

enter image description here

2

まあ、簡単な方法があります:これは、基本的にフラスコセキュリティ例のアプリが与えるのと同じ応答です。 Visit。構成項目WTF_CSRF_ENABLEDは、csrfを無効にする場合はFalseに設定できます。それから、あなたが望むようにすべてが行きます。

+1

これは私の問題を解決しました、ありがとうございます。セキュリティ機能を無効にするため、おそらく下落してしまいました。しかし、RESTサーバーがトークン認証のみを行い、Cookieベースの認証を行っていない場合、CSRFトークンは冗長です。 (私はこれに関するすべてのコメントを歓迎する!) – velotron