我有一个复杂的破折号应用程序,我想将其保留在受 JWT 保护的路线后面。我的最终目标是将它包含在单独路由上的 iframe 中,但我只希望用户能够获取 th dash 应用程序的 html,如果他们有访问令牌。
我已重试在获取请求中返回应用程序本身。
应用程序
import dash
from flask import Flask, jsonify, request
from flask_jwt_extended import (
JWTManager, jwt_required, create_access_token,
get_jwt_identity
)
server = Flask(__name__)
server.config['JWT_SECRET_KEY'] = 'super-secret' # Change this!
jwt = JWTManager(server)
@server.route('/login', methods=['POST'])
def login():
if not request.is_json:
return jsonify({"msg": "Missing JSON in request"}), 400
username = request.json.get('username', None)
password = request.json.get('password', None)
if not username:
return jsonify({"msg": "Missing username parameter"}), 400
if not password:
return jsonify({"msg": "Missing password parameter"}), 400 …Run Code Online (Sandbox Code Playgroud) 我想在调用 @jwt_required 时向令牌添加额外的验证。我想验证其中一项声明。我可以用 JWTManager 做到这一点吗?
目前我的代码只是调用:
jwt = JWTManager(app)
Run Code Online (Sandbox Code Playgroud)
我用以下方法装饰功能: @jwt_required
登录用户的令牌有效期为24小时.在此期间内,所有与@jwt_required装饰者的请求将使当前访问令牌的到期时间再延长24小时.最长有效期为168(24*7)小时.
可以使用access_token和refresh_token.
ret = {
'access_token': create_access_token(identity=username, fresh=True),
'refresh_token': create_refresh_token(identity=username)
}
Run Code Online (Sandbox Code Playgroud)
但这意味着来自我的applicatino的每个API调用将是两个请求:1.实际HTTP请求2.刷新身份验证令牌
@app.route('/refresh', methods=['POST'])
@jwt_refresh_token_required
def refresh():
current_user = get_jwt_identity()
ret = {
'access_token': create_access_token(identity=current_user)
}
return jsonify(ret), 200
Run Code Online (Sandbox Code Playgroud)
有没有办法隐式扩展身份验证令牌?
我有一个带有 @jwt_required 装饰器的函数。
class Test(Resource):
@jwt_required
def get(self):
return {"test": "ok" }
Run Code Online (Sandbox Code Playgroud)
当设置正确的 HTTP 标头时,它工作正常,即
Authentication: Bearer [TOKEN]
但是当令牌无效/错误或弄乱时,会引发 jwt.exceptions.DecodeError :
File "env/lib/python3.6/site-packages/flask_restplus/resource.py", line 44, in dispatch_request
resp = meth(*args, **kwargs)
File "env/lib/python3.6/site-packages/flask_jwt_extended/view_decorators.py", line 103, in wrapper
verify_jwt_in_request()
File "env/lib/python3.6/site-packages/flask_jwt_extended/view_decorators.py", line 32, in verify_jwt_in_request
jwt_data = _decode_jwt_from_request(request_type='access')
File "env/lib/python3.6/site-packages/flask_jwt_extended/view_decorators.py", line 267, in _decode_jwt_from_request
decoded_token = decode_token(encoded_token, csrf_token)
File "env/lib/python3.6/site-packages/flask_jwt_extended/utils.py", line 80, in decode_token
encoded_token, verify=False, algorithms=config.algorithm
File "env/lib/python3.6/site-packages/jwt/api_jwt.py", line 84, in decode
payload, _, _, _ = self._load(jwt)
File "env/lib/python3.6/site-packages/jwt/api_jws.py", …Run Code Online (Sandbox Code Playgroud) 我已经使用flask-restful和flask-jwt-extend构建了一个api,并正确配置了令牌过期和失效的验证通道。但是,即使构建了令牌过期和无效验证回调,api也无法正确处理并报告错误:签名已过期
在云服务器上,我们有一台 Centos 7 x64 16GB RAM,使用版本 19.9.0 的 Gunicorn 运行应用程序。使用 miniconda 创建应用程序的 python 环境。
在生产环境的测试中,应用程序抱怨令牌过期。然而,在测试环境中,使用 Ubuntu 18.04.2、x64 和 16 GB RAM,使用与 miniconda 和 Gunicorn 相同的设置,应用程序执行它没有问题,在令牌过期时返回正确的消息。
我的 jwt.py
from flask import Blueprint, Response, json, request
from flask_jwt_extended import (JWTManager, create_access_token,
create_refresh_token, get_jwt_identity,
jwt_required)
from app.models.core import User
from .schemas import UserSchema
from .utils import send_reponse, user_roles
def configure_jwt(app):
JWT = JWTManager(app)
@JWT.expired_token_loader
def my_expired_token_callback(expired_token):
return Response(
response=json.dumps({
"message": "Expired token"
}),
status=401,
mimetype='application/json'
)
@JWT.invalid_token_loader
def my_invalid_token_callback(invalid_token):
return Response(
response=json.dumps({ …Run Code Online (Sandbox Code Playgroud) flask-jwt-extended当我将装饰器token_in_blacklist_loader添加到我的代码中时,我遇到了这个奇怪的错误。这是错误:
Traceback (most recent call last):
File "home/app.py", line 42, in <module>
@jwt.token_in_blacklist_loader
AttributeError: 'JWTManager' object has no attribute 'token_in_blacklist_loader'
Run Code Online (Sandbox Code Playgroud)
这是我的代码:
@jwt.token_in_blacklist_loader
def check_if_token_is_revoked(decrypted_token):
jti = decrypted_token['jti']
token_in_redis = jwt_redis_blacklist.get(jti)
return token_in_redis is not None
Run Code Online (Sandbox Code Playgroud)
预先感谢您的宝贵反馈!
再次尝试制作我的第一个 Flask 应用程序,这一次(在我创建了我需要的所有内容并且一切顺利之后)我试图用 保护一些端点flask_jwt_extended,但我找不到如何在我的页面中使用它们,文档主要是关于显示 JSON 消息,一些教程使用 postman,而在我的例子中,我使用 HTML 模板。
例如,用户将其凭据从登录页面发送到此端点:
@app.route('/login', methods=['POST'])
def UserLogin():
data = parser.parse_args()
current_user = UserModel.find_by_username(data['username'])
if not current_user:
return {'message': 'User {} doesn\'t exist'.format(data['username'])}
if UserModel.verify_hash(data['password'], current_user.password):
access_token = create_access_token(identity = data['username'])
refresh_token = create_refresh_token(identity = data['username'])
resp = jsonify({'login': True}) #I just added this line from the documentation
set_access_cookies(resp, access_token) # and this one
set_refresh_cookies(resp, refresh_token) # and this one
return redirect(url_for('results'))
else:
return {'message': 'Wrong credentials'}
Run Code Online (Sandbox Code Playgroud)
当然,我将@jwt_required装饰器添加到results端点: …
在我的 app.py 中,我初始化了 flask-jwt-extended 如下:
# Setup the Flask-JWT-Extended extension
app.config['RESTPLUS_MASK_SWAGGER'] = False # remove default X-Fields field in swagger
app.config['JWT_SECRET_KEY'] = 'super-secret' # Change this!
app.config['JWT_BLACKLIST_ENABLED'] = True
app.config['JWT_BLACKLIST_TOKEN_CHECKS'] = ['access', 'refresh']
jwt = JWTManager(app)
Run Code Online (Sandbox Code Playgroud)
然后我使用代码段在登录中创建令牌:
expires = datetime.timedelta(minutes=10)
access_token = create_access_token(identity=payload['email'], fresh=True, expires_delta=expires)
refresh_token = create_refresh_token(identity=payload['email'])
Run Code Online (Sandbox Code Playgroud)
奇怪的是,如果我将装饰器 @jwt.token_in_blacklist_loader 添加到某个端点,我总是收到“令牌已被撤销”错误消息。
@jwt.token_in_blacklist_loader
@api.route('/')
class UserList(Resource):
@jwt_required
@api.doc('list_users')
@api.marshal_list_with(user)
def get(self):
'''Get all users'''
users = UserApi.query.all()
return users
Run Code Online (Sandbox Code Playgroud)
据我所知,这个装饰器是检查令牌是否被列入黑名单,我只是从登录创建一个新令牌,创建新令牌并检查令牌是否被列入黑名单的最佳实践是什么?
我只在 cookie 中设置访问令牌。但我在cookies中也发现了CSRF_token。我不明白为什么会发生以及它是如何发生的。
看我的代码:- 设置访问令牌。
access_token = create_access_token(identity=user.id, fresh=True)
refresh_token = create_refresh_token(identity=user.id)
resp=Response.SUCCESS(data={'id': user.id, 'refresh_token': refresh_token})
set_access_cookies(resp,access_token)
return resp
Run Code Online (Sandbox Code Playgroud)
饼干
当我使用@jwt_requiured((locations=['cookies'],fresh=True) 它时返回Missing CSRF token。在这里,我需要通过 header 传递 CSRF 令牌。有谁知道这里发生了什么?我应该做什么?
python access-token flask-restful flask-jwt-extended csrf-token
我的 Flask 应用程序使用 JWT 作为身份验证手段。这些令牌存储在 cookie 中,并且 Flask-jwt-extended 配置为使用它们。对于常规 GET 请求,身份验证工作正常,@jwt_required装饰器能够从 cookie 中读取令牌并对用户进行身份验证。但是,当使用fetch()扩展发出 AJAX POST 请求时,无法读取它们并返回Missing CSRF token错误。奇怪的是,当访问 POST 路由中的请求对象时,所有必需的 cookie 都存在,并且在经过身份验证时所有其他路由中都存在,这意味着fetch()正确设置所有必需的 cookie:
ImmutableMultiDict([
('csrftoken', 'valid_csrf_token'),
('session','valid_session_cookie'),
('access_token_cookie', 'valid_access_token'),
('csrf_access_token', 'valid_csrf_access_token')
])
Run Code Online (Sandbox Code Playgroud)
Flask POST 路线:
@main.route("/sendmail", methods=["POST"])
@jwt_required()
async def send_mail():
data = json.loads(request.data)
mail_template = render_template("mail-view.html", data=data)
pdf_report = pdfkit.from_string(mail_template, False)
message = Message(
subject="Flask-Mailing module",
recipients=["recepient-mail@domain.com"],
body="Message body",
subtype="html",
)
message.attach("report.pdf", pdf_report)
await mail.send_message(message)
return jsonify({"message": "success"}), 200
Run Code Online (Sandbox Code Playgroud)
获取请求:
fetch(window.location.origin …Run Code Online (Sandbox Code Playgroud) 我就像一个星期前才了解了flask和JWT,所以我真的可以使用一些帮助。有人可以解释flask-jwt和flask-jwt-extended之间的区别吗?
我已经尝试阅读文档并尝试更改默认行为https://flask-jwt-extended.readthedocs.io/en/latest/changing_default_behavior.html来处理错误(该链接显示了如何处理过期的令牌)和在谷歌中搜索我能做的每个关键字组合中的所有内容,但似乎没有人有这方面的例子。
我尝试使用 @jwt.revoked_token_loader 来处理 RevokedTokenError 但它似乎不起作用,因为我像这样应用它
@jwt.revoked_token_loader
def revoked_token_response(revoked_token):
jwtkn = revoked_token['jti']
return jsonsify({
'msg': 'token {} already been revoked!'.format(jwtkn)
)}, 401
Run Code Online (Sandbox Code Playgroud)
实际上,我不知道处理过期令牌的链接上的示例如何具有“expired_token”参数,这种自我声明是否像我上面在“revoked_token”上所做的那样?据我所知,“jti”就像flask-jwt-extended包中的默认值,因为每当我不使用它时我都会看到错误(在我的数据库中,它是不同的,但根本没有问题。
我尝试按照本教程进行操作,在我这边效果很好(以及他的原始代码源),但我发现这个在撤销令牌上也没有捕获异常https://codeburst.io/jwt-authorization-烧瓶内-c63c1acf4eeb
我使用邮递员,如果基于教程链接,这就是我如何得到这个
i do login
i use the access token generated to access protected routes ('/secrets')
i do logout
i use again the access token generated to access protected routes
Run Code Online (Sandbox Code Playgroud)
在最后一个之后,我在服务器端(ide)收到此错误:
....flask_jwt_extended\utils.py", line 216, in verify_token_not_blacklisted
raise RevokedTokenError('Token has been revoked')
flask_jwt_extended.exceptions.RevokedTokenError: Token has been revoked
127.0.0.1 -- [02/Jul/2019 22:25:26] "GET /secrets HTTP/1.1" 500 …Run Code Online (Sandbox Code Playgroud) python ×9
flask ×8
jwt ×6
cookies ×2
access-token ×1
bearer-token ×1
csrf-token ×1
flask-jwt ×1
plotly-dash ×1
token ×1