JWT の生成と検証
ここでは JSON Web Token (JWT) の生成方法と検証方法について実例をあげて説明します。
Express で認証のミドルウェアを作成するなどの例は「Express で JWT を用いた認証を実装する方法」をみてください。
$ npm install --save jsonwebtoken $ npm install --save @types/jsonwebtoken
JWT の生成は次のように行います。
import * as jwt from 'jsonwebtoken';
const jwtPayload = {
email: 'user1@example.com',
name: 'JWT Taro',
};
const jwtSecret = 'secret_key_goes_here';
const jwtOptions = {
algorithm: 'HS256',
expiresIn: '3s',
};
const token = jwt.sign(jwtPayload, jwtSecret, jwtOptions);
JWT の検証の大枠は次の通りです。
import * as jwt from 'jsonwebtoken';
const jwtSecret = 'secret_key_goes_here';
const token = '...';
// 検証
jwt.verify( token, jwtSecret, (err: any, decoded: any) => {
if (err) {
// エラー
} else {
// OK
}
});
トークンの作成と検証の動作確認
試しに、JWT トークンを生成して、直ちに検証してみましょう。
トークンの期限切れのテストのために、処理を止めたりするので下のコードを実行するには sleep パッケージも必要です。
$ npm install --save sleep $ npm install --save @types/sleep
import * as jwt from 'jsonwebtoken';
import * as sleep from 'sleep';
const jwtPayload = {
email: 'user1@example.com',
name: 'JWT Taro',
};
const jwtSecret = 'secret_key_goes_here';
const jwtOptions = {
algorithm: 'HS256',
expiresIn: '3s',
};
// Generate JWT token
console.log(`Payload: email=[${jwtPayload.email}], name=[${jwtPayload.name}]` );
console.log( '=== GENERATE JWT TOKEN ===');
const token = jwt.sign(jwtPayload, jwtSecret, jwtOptions);
console.log( `Token: ${token}` );
console.time( 'A' );
sleep.sleep( 1 );
console.timeEnd( 'A' );
// Verify JWT token
console.log( '=== VERIFY JWT TOKEN ===');
jwt.verify( token, jwtSecret, (err: any, decoded: any) => {
if (err) {
console.log( `ERROR: err.message=[${err.message}]` );
} else {
console.log( `OK: decoded.email=[${decoded.email}], name=[${decoded.name}]` );
}
});
この実行結果は次のようになりました。
Payload: email=[user1@example.com], name=[JWT Taro] === GENERATE JWT TOKEN === Token: eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJlbWFpbCI6InVzZXIxQGV4YW1wbGUuY29tIiwibmFtZSI6IkpXVCBUYXJvIiwiaWF0IjoxNTUwMzU2NzA1LCJleHAiOjE1NTAzNTY3MDh9.ZcF5pZC0vQerzQqNfYZ9_mghAuMoqfOVnVjSJf87EWU A: 1005.313ms === VERIFY JWT TOKEN === OK: decoded.email=[user1@example.com], name=[JWT Taro]
上の例では jwtOptions にて expiresIn: '3s' としています。
const jwtOptions = {
algorithm: 'HS256',
expiresIn: '3s',
};
つまり、トークンの有効期限は生成されてから 3 秒だけです。上のコードでは 1 秒だけスリープしてからトークンの検証をしています。(sleep に 1 を渡しているところが、1 秒スリープしているところです)
ここでコードを書き換え sleep で 5 秒スリープするようにしてみましょう。 すると、次のように verify メソッドでエラーが返ります。
... === VERIFY JWT TOKEN === ERROR: err.message=[jwt expired]
メッセージは確かに 'jwt expired' (jwt は有効期限切れです) となります。有効期限が 3 秒であるのに対して、5 秒経過してからトークンを検証しているので、正しく検証できたことがわかります。