🎃

JSON Web Tokenをどうやって信頼するのか

2023/02/21に公開

JSON Web Tokenとは

JSON Web Tokenとは、トークンベースの認証をする際に、サーバ側が発行したトークンのことである。ユーザがシステムでアクションを実行する際、このトークンを提示することにより、システムのサーバにおける本人確認が行われる。

トークンは、下記のようにランダムな文字列で構成される。

header, payload, signatureで構成されており、これらを複合化することで、そのユーザがどのような権限を保持するか、サーバ側で確認できる。例えばユーザがAmazonでショッピングする際、user名、権限、実行アクション(買い物はできるけど、商品編集はできない等)がトークンとして確認される。

payload, header, signatureとは

まずpayloadとheaderについて。

  • payloadはユーザ名やuser IDといった、そのユーザ固有の情報を保持している。
  • headerは、HS256といったトークン発行時の署名生成のアルゴリズム情報を保持している。

ではJSON Web Tokenが、「信頼に値するか否か」どうすれば認証できるか。具体的には、そのTokenが攻撃者により改ざんされたものではないと、どうすればサーバ側で確認できるのか。その際に必要となるのが、signatureである。

システムのサーバ側は、下記関数によりsignatureを発行する。
function(header, payload, SECRET) = SIGNATURE

secretとは、認証サービス側のサーバに保管された文字列であり、このsecretがないとheaderとpayloadを含む情報に対して署名することができない。そのため、secretがないとsignatureの発行ができない。発行する側のサーバが、このheader.payloadに対して署名することで、このJSON TOKENが認証されたものであることを示している。

実際のコードで学ぶ

まずpythonのパッケージとして、jwtとbase64をインポートする。前者はデータを暗号化する際に、後者は複合化する際に必要となる。

# Import Python Package
import jwt
import base64

次に、暗号化するデータを平文で作成する。ここでは、payload, algorithm, secretを定義している。

payload = {'school':'udacity'}
algo = 'HS256' #HMAC-SHA 256
secret = 'learning'

最後に、情報を暗号化する。下記の通り、暗号化して出力すると "b'eyJ0eXAiOiJKV1Qi..." と言った形で、暗号化されたデータが出力される。

encoded_jwt = jwt.encode(payload, secret, algorithm=algo)
print(encoded_jwt)

上記を複合化する際は、下記の通りである。

# Decode a JWT
decoded_jwt = jwt.decode(encoded_jwt, secret, verify=True)
print(decoded_jwt)

Discussion