将Flask安全角色与Flask JWT REST API一起使用

将Flask安全角色与Flask JWT REST API一起使用,rest,flask-security,flask-principal,flask-jwt,Rest,Flask Security,Flask Principal,Flask Jwt,我正在构建一个基于Flask的restapi,并使用flaskjwt处理jwtauth。我还想使用内置的角色管理和Flask安全性。但是,Flask Security的@roles\u required()decorator假设我在失败时显示一个Flask视图 这是我的令牌端点(按我的要求工作): 以下是对没有任何角色要求的资源的成功响应(仅使用@jwt_required),这也可以按照我的要求工作: $ http POST localhost:5000/auth/token username=

我正在构建一个基于Flask的restapi,并使用flaskjwt处理jwtauth。我还想使用内置的角色管理和Flask安全性。但是,Flask Security的@roles\u required()decorator假设我在失败时显示一个Flask视图

这是我的令牌端点(按我的要求工作):

以下是对没有任何角色要求的资源的成功响应(仅使用@jwt_required),这也可以按照我的要求工作:

$ http POST localhost:5000/auth/token username='test' password='test'
HTTP/1.0 200 OK
Content-Length: 192
Content-Type: application/json
Date: Sun, 08 Nov 2015 17:45:46 GMT
Server: Werkzeug/0.10.4 Python/3.5.0

{
    "access_token": "eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJpYXQiOjE0NDcwMDQ3NDYsIm5iZiI6MTQ0NzAwNDc0NiwiZXhwIjoxNDQ3MDA1MDQ2LCJpZGVudGl0eSI6MX0.RFIeaLuvJNM9fDjFYFQ7sh_WaDVU-_aM7e46tVJzlBQ"
}
$http GET localhost:5000/protected Authorization:'JWT eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJpYXQiOjE0NDcwMDQ3NDYsIm5iZiI6MTQ0NzAwNDc0NiwiZXhwIjoxNDQ3MDA1MDQ2LCJpZGVudGl0eSI6MX0.RFIeaLuvJNM9fDjFYFQ7sh_WaDVU-_aM7e46tVJzlBQ'
HTTP/1.0 200 OK
Content-Length: 25
Content-Type: text/html; charset=utf-8
Date: Sun, 08 Nov 2015 17:46:24 GMT
Server: Werkzeug/0.10.4 Python/3.5.0

<models.User[email=test]>
$http GET localhost:5000/受保护的授权:'JWT EYJ0Exaioijkv1qilcjHbgChiijiuzi1nij9.EYJYXqioj0ndcwmdq3ndysim5izii6mtq0nzawnd0niwizxhwijoxndq3mda1mdq2lcjpzgvudgl0esi6mx0.rfiealuvjnm9fdjfyfyfq7sh_WaDVU-'am7e46vjzl'
HTTP/1.0 200正常
内容长度:25
内容类型:text/html;字符集=utf-8
日期:2015年11月8日星期日17:46:24 GMT
服务器:Werkzeug/0.10.4 Python/3.5.0
当我对具有所需角色的资源(如本例中的管理员)执行相同操作时,似乎假设我有一个页面要显示,如/login,但我没有,因为它是一个无头REST API:

$ http GET localhost:5000/admin Authorization:'JWT eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJpYXQiOjE0NDcwMDQ3NDYsIm5iZiI6MTQ0NzAwNDc0NiwiZXhwIjoxNDQ3MDA1MDQ2LCJpZGVudGl0eSI6MX0.RFIeaLuvJNM9fDjFYFQ7sh_WaDVU-_aM7e46tVJzlBQ'
HTTP/1.0 302 FOUND
Content-Length: 209
Content-Type: text/html; charset=utf-8
Date: Sun, 08 Nov 2015 17:46:43 GMT
Location: http://localhost:5000/
Server: Werkzeug/0.10.4 Python/3.5.0
Set-Cookie: session=eyJfZmxhc2hlcyI6W3siIHQiOlsiZXJyb3IiLCJZb3UgZG8gbm90IGhhdmUgcGVybWlzc2lvbiB0byB2aWV3IHRoaXMgcmVzb3VyY2UuIl19XX0.CSEcAw.pjwXLeSWUsORXR-OU5AfFvq6ESg; HttpOnly; Path=/

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2 Final//EN">
<title>Redirecting...</title>
<h1>Redirecting...</h1>
<p>You should be redirected automatically to target URL: <a href="/">/</a>.  If not click the link.
$http GET LOCAL HOST:5000/管理员授权:'JWT EYJ0Exaioijkv1qilcjHbggioijiuzi1nij9.EYJPYXQiOjE0ndCwMDQ3ndysim5izii6mtq0nzawnd0niwizxhwijoxndq3mda1mdq2lcjpzvudgl0esi6mx0.rfiealuvjnm9fdjfyfyfq7sh_WaDVU-'am7e46vjzl'
找到HTTP/1.0 302
内容长度:209
内容类型:text/html;字符集=utf-8
日期:2015年11月8日星期日17:46:43 GMT
地点:http://localhost:5000/
服务器:Werkzeug/0.10.4 Python/3.5.0
设置Cookie:session=eyjfzmxhc2hlcyi6w3siihqiolsizzjyb3iilczb3ugzg8gbm90ighhdmugcgvybwlzc2lvib0byb2awv3ihroaxmgcmvzb3vyy2uuil19xx0.CSEcAw.pjwXLeSWUsORXR-OU5AfFvq6ESg;HttpOnly;路径=/
重定向。。。
重定向。。。
您应该自动重定向到目标URL:。如果没有,请单击链接。
我知道Flask Security在幕后使用Flask Principal进行角色管理(@roles_required,等等),它与数据存储的RoleMixin和UserMixin绑定,这非常好。但是,如果没有办法让Flask安全性只允许资源通过而不使用我的JWT头,那么最好的办法可能是构建我自己的decorator,它使用Flask主体来管理角色

有没有人有这方面的经验?我们的想法是,整个前端可以并且将以我们需要的任何语言构建,这意味着它可能不是Flask的模板/视图,而Flask Security似乎正在做这件事


感谢您提供的任何见解

您希望使用HTTP状态代码403来响应,而不是重定向

你最好的办法就是创建自己的装饰器来管理角色,并完全不再使用
Flask-Security

Flask Security
的作者指出,有更好的方法来保护api,而且由于没有维护库,这更有意义

Flask JWT
Flask JWT Extended
是完成此任务的理想人选。前者需要更多的样板文件才能使事情顺利进行。有一个API建议支持角色,如果您决定使用
flaskjwt
,您可以使用它来创建自己的装饰器

Flask JWT Extended
文档建议了一个更简单的解决方案,可能适合您的情况。对于完整的示例,您应该按照文档中的一节进行操作,但简而言之,这里是decorator:

从functools导入包装
从flask导入jsonify
从flask_jwt_扩展导入(
在请求中验证,获取索赔
)
需要def管理员(fn):
@包装(fn)
def包装(*args,**kwargs):
验证请求()中的jwt
索赔=获取索赔()
如果声明['roles']!='管理员':
返回jsonify(msg='Admins only!'),403
其他:
返回fn(*args,**kwargs)
返回包装器

此代码在JWT中查找
角色
声明,如果它不是
管理员

您有过任何进展吗?@MikeDavlantes我们最终没有机会这样做,因为我不得不转到一家新公司,抱歉:/