发送带有承载令牌授权标头 (flask_restful + flask_jwt_extended) 的 GET 消息时出现“段不足”

Posted

技术标签:

【中文标题】发送带有承载令牌授权标头 (flask_restful + flask_jwt_extended) 的 GET 消息时出现“段不足”【英文标题】:"Not enough segments" when seding a GET message with Bearer Token Authorization Header (flask_restful + flask_jwt_extended) 【发布时间】:2020-08-09 15:51:23 【问题描述】:

我在 Flask 应用程序中收到此错误:

curl http://0.0.0.0:8080/ -H "Authorization: Bearer TGazPL9rf3aIftplCYDTGDc8cbTd"

  "msg": "Not enough segments"

这里是一个示例:

from flask import Flask
from flask_restful import Resource, Api
from flask_jwt_extended import JWTManager, jwt_required

app = Flask(__name__)
jwt = JWTManager(app)
api = Api(app)


class HelloWorld(Resource):
    @jwt_required
    def get(self):
        return 'hello': 'world'


api.add_resource(HelloWorld, '/')

控制台:

 * Serving Flask app "app.py" (lazy loading)
 * Environment: development
 * Debug mode: on
 * Running on http://0.0.0.0:8080/ (Press CTRL+C to quit)
 * Restarting with stat
 * Debugger is active!
 * Debugger PIN: 890-265-009
127.0.0.1 - - [26/Apr/2020 02:02:32] "GET / HTTP/1.1" 422 -

我不明白:怎么了?

该异常已在其他库中引发(site-packages/jwt/api_jws.py 中的第 183 行):

  def _load(self, jwt):
        if isinstance(jwt, text_type):
            jwt = jwt.encode('utf-8')

        if not issubclass(type(jwt), binary_type):
            raise DecodeError("Invalid token type. Token must be a 0".format(
                binary_type))

        try:
            signing_input, crypto_segment = jwt.rsplit(b'.', 1)
            header_segment, payload_segment = signing_input.split(b'.', 1)
        except ValueError:
            raise DecodeError('Not enough segments')

【问题讨论】:

【参考方案1】:

您尝试传入的令牌 (TGazPL9rf3aIftplCYDTGDc8cbTd) 不是有效的 JWT。一个有效的 JWT 包含三个由点分隔的段:<base64_encoded_header>.<base64_encoded_payload>.<signature>。你可以在这里阅读更多信息:https://jwt.io/introduction/

【讨论】:

【参考方案2】:

我将在此处发布与我上面最初的问题相关的答案,上下文是我试图用户 flask_jwt_extend 用于 firebase 身份验证,但我有这个“没有足够的段”错误,我被阻止了。

所以在那之后,我将我的代码更改为:

from flask import Flask, request
from flask_restful import Resource, Api
from functools import wraps
import google.auth.transport.requests
import google.oauth2.id_token

app = Flask(__name__)
api = Api(app)
HTTP_REQUEST = google.auth.transport.requests.Request()


def jwt_required_gcp(fn):
    @wraps(fn)
    def wrapper(*args, **kwargs):
        id_token = request.headers['Authorization'].split(' ').pop()
        claims = google.oauth2.id_token.verify_firebase_token(
            id_token, HTTP_REQUEST)
        if not claims:
            return 'Unauthorized', 401
        return fn(*args, **kwargs)
    return wrapper


class HelloWorld(Resource):
    @jwt_required_gcp
    def get(self):
        return 'hello': 'world'


api.add_resource(HelloWorld, '/')

【讨论】:

【参考方案3】:

检查您的 JWT 令牌。有效吗?

@fresh_jwt_required - fresh_jwt_required() 函数只允许新令牌访问特定端点

@jwt_required - 使用 JSON Web 令牌保护 Flask 端点的装饰器。任何使用此修饰的路由都需要在请求中存在有效的 JWT(除非 optional=True,在这种情况下,没有 JWT 也是有效的),然后才能调用端点。

更多详情请查看flask-jwt-extended

【讨论】:

上面标记的答案无效(来自vimalloc)

以上是关于发送带有承载令牌授权标头 (flask_restful + flask_jwt_extended) 的 GET 消息时出现“段不足”的主要内容,如果未能解决你的问题,请参考以下文章

在 Asp.Net Core 中使用 Swagger 在请求中未发送授权承载令牌

如何在授权标头中将带有 fetch 和 cors 的 JWT 令牌发送到 Express 服务器?

使用授权承载请求时在 Firebase 函数中获取令牌

如何将承载令牌添加到 HTTP 请求的标头?

如何在 Ionic 4 中发送带有标头的身份验证令牌?

React.js JWT Socket.io 身份验证