2013-08-26 155 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