📑

【Python】JWT tokenのデコードエラー

2023/03/26に公開

概要

UdacityのCoffee Shop Appの開発をしていて、Backendのエラーが発生した。具体的には、下記URLに対してGETリクエストを送信したところ、JWTデコードのエラーが発生した。
http://127.0.0.1:5000/drinks-detail

drinks-deitalはJWT認証が求められるため、その認証が通らないという状況。jwt.ioでtokenを確認しても、正しくユーザ権限が割り当てられていた。具体のエラーは下記の通り。

[2023-03-26 17:48:13,554] ERROR in app: Exception on /drinks-detail [GET]
Traceback (most recent call last):
  File "/Library/Frameworks/Python.framework/Versions/3.7/lib/python3.7/site-packages/jose/jws.py", line 179, in _load
    signing_input, crypto_segment = jwt.rsplit(b'.', 1)
ValueError: not enough values to unpack (expected 2, got 1)

エラーの原因 & 対応策

上記エラーは、JWTトークンが不正な形式だったため発生した。トークン自体が不正という意味ではなく、正しいフォーマットで送信できていなかったということ。本来、JWTトークンは、「bear header.payload.signature」という形で送信される。自分のコードでは、bearとそれ以降の文字を" "により分割すべきだったが、"."により分割していた。

自分の誤ったコード

def get_token_auth_header():
    if 'Authorization' not in request.headers: 
        abort(401)
    auth_header = request.headers['Authorization']
    header_parts = auth_header.split('.')
    if len(header_parts) != 3:
        abort(401)
    return header_parts[1]

ヘッダーがBearとトークンで構成されていることを確認して、分割された部分の長さをチェックして、トークン部分を返すように修正した。
正しいコード

def get_token_auth_header():
    if 'Authorization' not in request.headers: 
        abort(401)
    auth_header = request.headers['Authorization']
    header_parts = auth_header.split(' ')
    if len(header_parts) != 2 or header_parts[0].lower() != 'bearer':
        abort(401)
    return header_parts[1]

豆知識

上記と関連して、http://127.0.0.1:5000/drinks-detail に対して、誤ったリクエストを送ると、下記エラーが発生する。

value contains drinks array | AssertionError: expected undefined to be an array

どういうエラーか説明すると、drinks-detailエンドポイントから、適切な形式のJSONレスポンスが返されていないということ。正しいレスポンスが返るように、修正する必要がある。

Discussion