JSON Web Tokenをどうやって信頼するのか
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