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 秒だけスリープしてからトークンの検証をしています。(sleep1 を渡しているところが、1 秒スリープしているところです)

ここでコードを書き換え sleep で 5 秒スリープするようにしてみましょう。 すると、次のように verify メソッドでエラーが返ります。

...
=== VERIFY JWT TOKEN ===
ERROR: err.message=[jwt expired]

メッセージは確かに 'jwt expired' (jwt は有効期限切れです) となります。有効期限が 3 秒であるのに対して、5 秒経過してからトークンを検証しているので、正しく検証できたことがわかります。

ここまでお読みいただき、誠にありがとうございます。SNS 等でこの記事をシェアしていただけますと、大変励みになります。どうぞよろしくお願いします。

© 2024 Node.js 入門