![](/img/trans.png)
[英]Using flask-jwt-extended callbacks with flask-restful and create_app
[英]Having issues using Flask-JWT-Extended with Flask-Restful
我正在按照“Python API Fundamentals”一书中的步骤使用 Flask-Restful 构建 API。 我遇到的问题是我无法获得令牌。 我的代码是书中内容的编辑副本,每当我在 Postman 上进行测试时,它都会抛出以下错误
127.0.0.1 - - [01/Aug/2022 13:26:49] "POST /token HTTP/1.1" 500 -
Traceback (most recent call last):
File "C:\Users\TARI\Documents\GitHub\understand_api_development_with_python\basic-api\venv\Lib\site-packages\flask\app.py", line 2091, in __call__
return self.wsgi_app(environ, start_response)
File "C:\Users\TARI\Documents\GitHub\understand_api_development_with_python\basic-api\venv\Lib\site-packages\flask\app.py", line 2076, in wsgi_app
response = self.handle_exception(e)
File "C:\Users\TARI\Documents\GitHub\understand_api_development_with_python\basic-api\venv\Lib\site-packages\flask_restful\__init__.py", line 271, in error_router
return original_handler(e)
File "C:\Users\TARI\Documents\GitHub\understand_api_development_with_python\basic-api\venv\Lib\site-packages\flask\app.py", line 2073, in wsgi_app
response = self.full_dispatch_request()
File "C:\Users\TARI\Documents\GitHub\understand_api_development_with_python\basic-api\venv\Lib\site-packages\flask\app.py", line 1519, in full_dispatch_request
rv = self.handle_user_exception(e)
File "C:\Users\TARI\Documents\GitHub\understand_api_development_with_python\basic-api\venv\Lib\site-packages\flask_restful\__init__.py", line 271, in error_router
return original_handler(e)
File "C:\Users\TARI\Documents\GitHub\understand_api_development_with_python\basic-api\venv\Lib\site-packages\flask\app.py", line 1517, in full_dispatch_request
rv = self.dispatch_request()
File "C:\Users\TARI\Documents\GitHub\understand_api_development_with_python\basic-api\venv\Lib\site-packages\flask\app.py", line 1503, in dispatch_request
return self.ensure_sync(self.view_functions[rule.endpoint])(**req.view_args)
File "C:\Users\TARI\Documents\GitHub\understand_api_development_with_python\basic-api\venv\Lib\site-packages\flask_restful\__init__.py", line 467, in wrapper
resp = resource(*args, **kwargs)
File "C:\Users\TARI\Documents\GitHub\understand_api_development_with_python\basic-api\venv\Lib\site-packages\flask\views.py", line 84, in view
return current_app.ensure_sync(self.dispatch_request)(*args, **kwargs)
File "C:\Users\TARI\Documents\GitHub\understand_api_development_with_python\basic-api\venv\Lib\site-packages\flask_restful\__init__.py", line 582, in dispatch_request
resp = meth(*args, **kwargs)
File "C:\Users\TARI\Documents\GitHub\understand_api_development_with_python\smilecook\resources\token.py", line 24, in post
access_token = create_access_token(identity=user.id)
File "C:\Users\TARI\Documents\GitHub\understand_api_development_with_python\basic-api\venv\Lib\site-packages\flask_jwt_extended\utils.py", line 157, in create_access_token
return jwt_manager._create_access_token(identity, fresh, expires_delta, user_claims)
File "C:\Users\TARI\Documents\GitHub\understand_api_development_with_python\basic-api\venv\Lib\site-packages\flask_jwt_extended\jwt_manager.py", line 469, in _create_access_token
access_token = encode_access_token(
File "C:\Users\TARI\Documents\GitHub\understand_api_development_with_python\basic-api\venv\Lib\site-packages\flask_jwt_extended\tokens.py", line 76, in encode_access_token
return _encode_jwt(token_data, expires_delta, secret, algorithm,
File "C:\Users\TARI\Documents\GitHub\understand_api_development_with_python\basic-api\venv\Lib\site-packages\flask_jwt_extended\tokens.py", line 31, in _encode_jwt
json_encoder=json_encoder).decode('utf-8')
AttributeError: 'str' object has no attribute 'decode'
这是我的要求.txt
Flask==2.1.3
Flask-RESTful==0.3.9
httpie==3.2.1
Flask-SQLAlchemy==2.5.1
Flask-Migrate==3.1.0
psycopg2-binary==2.9.3
passlib==1.7.4
Flask-JWT-Extended==3.20.0
Werkzeug==2.0
以及我认为导致问题的代码
from http import HTTPStatus
from flask import request
from flask_restful import Resource
from flask_jwt_extended import create_access_token
from utils import check_password
from models.user import User
class TokenResource(Resource):
def post(self):
json_data = request.get_json()
email = json_data.get('email')
password = json_data.get('password')
user = User.get_by_email(email=email)
if not user or not check_password(password, user.password):
return {'message': 'username or password is incorrect'}, HTTPStatus.UNAUTHORIZED
access_token = create_access_token(identity=user.id)
return {'access_token': access_token}, HTTPStatus.OK
from flask import request
from flask_restful import Resource
from flask_jwt_extended import jwt_optional, get_jwt_identity
from http import HTTPStatus
from utils import hash_password
from models.user import User
class UserListResource(Resource):
def post(self):
json_data = request.get_json()
username = json_data.get('username')
email = json_data.get('email')
non_hash_password = json_data.get('password')
if User.get_by_username(username):
return {'message': 'username already used'}, HTTPStatus.BAD_REQUEST
if User.get_by_email(email):
return {'message': 'email already used'}, HTTPStatus.BAD_REQUEST
password = hash_password(non_hash_password)
user = User(
username=username,
email=email,
password=password
)
user.save()
data = {
'id': user.id,
'username': user.username,
'email': user.email
}
return data, HTTPStatus.CREATED
class UserResource(Resource):
@jwt_optional
def get(self, username):
user = User.get_by_username(username=username)
if user is None:
return {'message': 'user not found'}, HTTPStatus.NOT_FOUND
current_user = get_jwt_identity()
if current_user == user.id:
data = {
'id': user.id,
'username': user.username,
'email': user.email,
}
else:
data = {
'id': user.id,
'username': user.username,
}
return data, HTTPStatus.OK
from flask import Flask
from flask_migrate import Migrate
from flask_restful import Api
from config import Config
from extensions import db, jwt
from resources.user import UserListResource, UserResource
from resources.token import TokenResource
from resources.recipe import RecipeListResource, RecipeResource, RecipePublishResource
def create_app():
app = Flask(__name__)
app.config.from_object(Config)
register_extensions(app)
register_resources(app)
return app
def register_extensions(app):
db.init_app(app)
migrate = Migrate(app, db)
jwt.init_app(app)
def register_resources(app):
api = Api(app)
api.add_resource(UserListResource, '/users')
api.add_resource(UserResource, '/users/<string:username>')
api.add_resource(TokenResource, '/token')
api.add_resource(RecipeListResource, '/recipes')
api.add_resource(RecipeResource, '/recipes/<int:recipe_id>')
api.add_resource(RecipePublishResource, '/recipes/<int:recipe_id>/publish')
if __name__ == '__main__':
app = create_app()
app.run()
pip freeze
的结果
alembic==1.8.1
aniso8601==9.0.1
certifi==2022.6.15
charset-normalizer==2.1.0
click==8.1.3
colorama==0.4.5
commonmark==0.9.1
defusedxml==0.7.1
Flask==2.1.3
Flask-JWT-Extended==3.20.0
Flask-Migrate==3.1.0
Flask-RESTful==0.3.9
Flask-SQLAlchemy==2.5.1
greenlet==1.1.2
httpie==3.2.1
idna==3.3
itsdangerous==2.1.2
Jinja2==3.1.2
Mako==1.2.1
MarkupSafe==2.1.1
multidict==6.0.2
passlib==1.7.4
psycopg2-binary==2.9.3
Pygments==2.12.0
PyJWT==2.4.0
PySocks==1.7.1
pytz==2022.1
requests==2.28.1
requests-toolbelt==0.9.1
rich==12.5.1
six==1.16.0
SQLAlchemy==1.4.39
urllib3==1.26.11
Werkzeug==2.0.0
发生这种情况是因为您有一个较新版本的 PyJWT 与旧版本的 flask jwt 扩展不兼容。 将 flask jwt 升级到至少 3.25.0 应该可以解决此问题。 如果您升级到 flask jwt 扩展版的 4.xx 版本,请务必阅读此处的重大更改: https://flask/jwt-extended.
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.